欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue之全局API(nextTick、filter、use)

程序员文章站 2024-02-18 20:43:35
...

全局API

  • (1)什么是全局API?
    全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API.
    通俗理解:就是在构造器外部Vue提供的API函数定义新的功能
  • (2)常用vue 的全局 API列表
    1、Vue.directive 自定义指令
    2、Vue.extend 扩展实例构造器
    3、全局操作Vue.set + Vue.delete
    4、Vue 的生命周期
    5、Vue component 组件 + Vue template模板
    6、Vue.nextTick线程操作、Vue.filter筛选、Vue.use调用
  • 小结:全局API就是在构造器外部用Vue提供的API函数来定义新的功能。

Vue.nextTick线程操作

  • Vue.nextTick线程操作
    语法:Vue.nextTick([callback,context])
  • 作用:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,即可获取更新后的 DOM
  • 案例:点击按钮,修改姓名并获取更新后的DOM元素内容
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
  • 分析:测试后可以看到视图更新以后拿到的并不是更新后的innerHTML
  • 原因:因为DOM结构更新是一个异步事件.
    案例二具体代码如下:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div class="demo">
			<h1>{{name}}</h1>
			<button @click="changeName">change</button>
		</div>
	</body>
	<script type="text/javascript">
		
		var demo = new Vue({
			el:'.demo',
			data:{
				name:"蜡笔小新"
			},
			methods:{
				changeName:function(){
					this.name = "阿呆"
					this.$nextTick(function(){
						//打印出阿呆
						console.log(document.getElementsByTagName('h1')[0].innerHTML)
					})
					//document.getElementsByTagName('h1')[0].innerHTML
					//直接打印是异步处理,仍然打印出蜡笔小新
				}
			}
		})
	</script>
</html>

  • 分析案例一:深入响应式原理
    Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。
    $nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM。
    Vue之全局API(nextTick、filter、use)
  • 结合上述,目前已经知道Vue.nextTick操作的作用,接下来深入分析下原理,先来了解几个概念。
    1、异步过程:数据变化到dom变化是异步过程
    2、核心实现:nextTick 是 Vue 的一个核心实现,为了方便大家理解,简单介绍一下 JS 的运行机制。
    3、JS 运行机制:JS 执行是单线程的,它是基于事件循环的。

JS运行机制

  • JS 执行是单线程的,它是基于事件循环的。事件循环大致分为以下几个步骤:
  • (1)执行栈
    所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)
  • (2)任务队列
    主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件(根据放置先后时间顺序决定事件执行顺序)。
  • (3)读取任务队列
    一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
  • (4)重复执行
    接下来主线程不断重复上面的第三步
  • 小结:
    主线程的执行过程就是一个 tick,而所有的异步结果都是通过 “任务队列” 来调度被调度。 消息队列中存放的是一个个的任务(task)。
  • 执行栈与任务队列:
    1、JS分为同步任务和异步任务
    2、同步任务都在主线程上执行,形成一个执行栈
    3、主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放置一个事件。
    4、一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
    例如代码如下:
<script type="text/javascript">
		/* 同步事件的优先级大于异步事件 */
		console.log(1)/* 同步事件 */
		setTimeout(function(){/* 异步事件 */
			console.log(2)
		},1000)
		console.log(3)/* 同步事件 */
	</script>
  • 执行栈与任务队列概念图
    Vue之全局API(nextTick、filter、use)

Vue.nextTick小结

  • 应用场景:
    Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM。
  • 通俗理解:
    vue响应式的改变一个值以后,此时的dom并不会立即更新,如果需要在数据改变以后立即通过dom做一些操作,可以使用$nextTick获得更新后的dom。

Vue.use

  • (3)工程化使用组件
    在用Vue使用别人的组件或者第三方库时,会用到 Vue.use(),如下所示

Vue之全局API(nextTick、filter、use)

filter过滤器

  • 【前言】
    过滤器顾名思义,过滤就是一个数据经过了这个过滤之后出来另一样东西,可以是从中取得你想要的,或者给那个数据添加点什么装饰,那么过滤器则是过滤的工具。
    应用场景:例如从[‘abc’ ,‘abd’,‘ade’]数组中取得包含‘ab’的值,那么可通过过滤器筛选出来‘abc’和‘abd’;把‘Hello’变成‘Hello World’,那么可用过滤器给值‘Hello’后面添加上‘ World’等等都可以使用过滤器,再例如价格3000,展示¥3000。
  • 【官方文档描述】
    Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化
    过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
    过滤器应该被添加在 JavaScript 表达式的尾部,由==“管道”符号|指示==
    Vue之全局API(nextTick、filter、use)
  • (4)Vue.filter过滤器分类
    Vue过滤器分为全局和局部两种,全局注册的过滤器为全局过滤器,局部注册的过滤器为局部过滤器。
    区别作用域不同,全局过滤器可以在全局内调用,局部过滤器只能在被定义的当前构造器下使用。
  • 通俗理解:过滤器可在new Vue实例前注册全局的,也可以在组件上写局部过滤器。
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
  • 调用过滤器包含两种方式
    文本插值表达式方式
    v-bind属性表达式中使用
  • 首先看下第一种文本插值表达式方式,案例需求:日常开发里,商品展示时一般都是“¥200”的格式。但这里注意,后台传过来的数据一般只包含纯数字,所以需要给数字添加货币¥标识,此时便涉及到filter过滤,给数据添加装饰¥,那么过滤器则是过滤的工具。
  • ①文本插值表达式方式—全局注册
    Vue之全局API(nextTick、filter、use)
    接下来使用局部注册的过滤器进行货币过滤,即给价格数据添加”美元$”标识,代码如下:
    Vue之全局API(nextTick、filter、use)
  • (4)Vue.filter过滤器优先级
  • 当全局过滤器和局部过滤器重名时,会优先采用局部过滤器
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
    假如不用.filter过滤器而是用computed计算属性也可以做出来,代码如下:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div class="demo">
			<h1>{{name}}---{{priceComputed}}</h1>
		</div>
	</body>
	<script type="text/javascript">
		var demo = new Vue({
			el: '.demo',
			data: {
				name: "vivo",
				price: 3000
			},
			computed:{
				priceComputed:function(){
				    return "¥" + this.price
				}
			}
		})
	</script>
</html>

Vue.filter过滤器具体代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div class="demo">
			<h1>{{name}}---{{price | filterMoney |$filterMoney}}</h1>
		</div>
	</body>
	<script type="text/javascript">
		/* 注意Vue.filter的过滤器重名的时候,优先用局部 */
		/* 全局注册 */
		Vue.filter('filterMoney',function(value){
			/* value值指的是price */
			return '¥'+value
		})
		/* 构造器 */
		var demo = new Vue({
			el: '.demo',
			data: {
				name: "vivo",
				price: 3000
			},
			/* 局部注册 */
			filters:{
				$filterMoney:function(value){
					return value+"特价"
				}
			}
		})
	</script>
</html>

  • v-bind表达式中使用(样式及内容显示)
  • 案例需求:
    有一个列表,类似微博粉丝关注,列表中有两种情况:已关注和未关注,需要在加载页面时进行样式区分
  • 功能分析及实现:
    ①通过过滤器来判断列表中每一项的显示颜色
    ②通过过滤器来判断内容显示"关注"与"已关注"
    ③type为0 ‘未关注’, type为1 ‘已关注’
  • 步骤1:内容过滤显示(筛选条件:type为0时未关注、type为1时已关注)
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
  • ②v-bind表达式中使用(样式及内容显示)
    步骤2:样式过滤展示(筛选条件:已关注字体为红色,未关注为绿色)
    Vue之全局API(nextTick、filter、use)
    1、定义局部颜色过滤器
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
    2、通过管道符链接,调用注册的局部颜色过滤器
    步骤2:样式过滤展示(筛选条件:已关注字体为红色,未关注为绿色)
    Vue之全局API(nextTick、filter、use)
    具体代码如下:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
		<style type="text/css">
			.no{
				color:green;
			}
			.yes{
				color: red;
			}
		</style>
	</head>
	<body>
		<div class="demo">
			<ul>
				<li v-for="Person of Persons" v-bind:class="Person | filterColor">
					{{Person.name}}--{{Person | filterPerson}}
				</li>
			</ul>
		</div>
	</body>
	<script type="text/javascript">
		/* 全局注册过滤器 */
		Vue.filter('filterPerson',function(value){
			/* value值指的是Person */
			return value.type == 0?'未关注':'已关注'
		})
		Vue.filter('filterColor',function(value){
			return value.type == 0?'no':'yes'
		})
		/* 构造器 */
		var demo = new Vue({
			el: '.demo',
			data:{
				/* 非0即真,0代表没关注,1代表关注 */
				Persons:[
					{type:1,name:'杨幂'},
					{type:0,name:'邓超'},
					{type:1,name:'李易峰'},
					{type:0,name:'鹿晗'}
				]
			}
		})
	</script>
</html>

  • List item(4)Vue.filter过滤器串联/过滤器的参数写法/管道式连接过滤
    过滤器除了可以单个使用外,也可以串联,利用管道符号 | 即可串联。
    案例:对于返回价格进行四舍五入过滤操作,然后加上货币过滤操作
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
  • 语法1:{{message | filterA | filterB …}}
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
    具体代码如下:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div class="demo">
			<p>{{name}}</p>
			<!-- filters在局部注册了过滤器 -->
			<!--{{price | filterRound | filterMoney}}对数量没有限制 -->
			<p>{{price | filterRound | filterMoney}}</p>	
		</div>
	</body>
	<script type="text/javascript">
		/* 构造器 */
		var demo = new Vue({
			el: '.demo',
			data:{
				name:'哈士奇',
				price:200.6
			},
			/* 局部注册过滤器 */
			filters:{
				filterRound:function(value){
					/* 四舍五入price的价钱 */
					return Math.round(value)
				},
				filterMoney:function(value){
					return "¥" + value +'元'
				}
			}
		})
	</script>
</html>

  • 语法2:{{message | filterA(option1,option2,…,optionN)}}

Vue之全局API(nextTick、filter、use)
Vue之全局API(nextTick、filter、use)
具体代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div class="demo">
			<h2>
				日期:{{time | filterTime(year,month,day)}}
			</h2>
		</div>
	</body>
	<script type="text/javascript">
		/* 构造器 */
		var demo = new Vue({
			el: '.demo',
			data:{
				time:'今天:',
				year:2019,
				month:11,
				day:9
			},
			/* 局部注册过滤器 */
			filters:{
				filterTime:function(value,option1,option2,option3){
					return value + option1 + '-' + option2 + '-' + option3
				}
			}
		})
	</script>
</html>

  • 语法3: {{ option1 , option2 , … ,optionN | filterA }}
    Vue之全局API(nextTick、filter、use)
    Vue之全局API(nextTick、filter、use)
    具体代码如下:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div class="demo">
			<h2>
				<!-- option1和option2、option3分别作为参数传给filterTime过滤器 -->
				日期:{{year,month,day |filterTime}}
			</h2>
		</div>
	</body>
	<script type="text/javascript">
		/* 构造器 */
		var demo = new Vue({
			el: '.demo',
			data:{
				year:2019,
				month:11,
				day:9
			},
			/* 局部注册过滤器 */
			filters:{
				/* option1和option2、option3分别作为参数传给filterTime过滤器 */
				filterTime:function(option1,option2,option3){
					return  option1 + '-' + option2 + '-' + option3
				}
			}
		})
	</script>
</html>

Vue.filter过滤器限制

  • (5)Vue.filter的this指向问题
    注意:
    Vue.filter中this指向并不是Vue实例,而是window。
    原因:
    vue中的过滤器更偏向于对文本数据的转化,而不能依赖this上下文,如果需要使用到上下文this我们应该使用computed计算属性的或者一个method方法。
    Vue之全局API(nextTick、filter、use)

computed&&filters

  • 【前言】
    目前为止,结合上述filter筛选案例,可以看出过滤器filter和计算属性computed实现的效果类似,就是将数据展示做些简单处理,实现了模板和逻辑代码的分离,减少了代码的耦合性。
  • 【computed和filters区别】
    相同点:所得到的值都需要return出去
  • 【computed和filters区别】
    • 1、computed
      ①不能传参,只能监听预先设置好的值
      ②值会缓存,在我们要监听的数据没有变化的时候,是不会再去执行对象相应的数据的(性能比较好)
    • 2、filter
      ①将返回数据进行处理后返回处理结果的简单函数
      ②值不会缓存,会重新执行里面的操作
  • 差异对比:
    • 1、computed计算属性常用于处理复杂逻辑,基于依赖缓存,当依赖发生改变时会重新取值
    • 2、methods方法也可以实现同样的效果,但methods在重新渲染的时候会重新调用执行,在性能上computed优于methods,当不需要缓存时可用methods。
    • 3、fliter过滤器是将返回数据进行处理后返回处理结果的简单函数
  • 问题:
    • filter主要用于数据转化,为什么不用computed呢?computed具有缓存作用,感觉比filter性能好,filter不就跟methods差不多吗
  • 分析:
    • 1、filter 可以串联 比如这样{{value | filterA | filterB}},在针对某些属性值的情况下使用起来更优雅,耦合性更低
    • 2、filter全局注册后复用性更高,不用每个page都引入方法,而computed适合本页面/组件的数据转换

今日小结

  • 1、注册—①全局Vue.filter;②局部filters选项

  • 2、调用—①文本插值表达式方式;②v-bind表达式中使用

  • 3、串联—过滤器串联/过滤器的参数写法/管道式连接过滤
    ①{{message | filterA | filterB}}
    ②{{message | filterA(option1,option2,…,optionN)}}
    ③{{ option1 , option2 , … ,optionN | filterA }}

  • 4、优先级—当全局过滤器和局部过滤器重名时,会优先采用局部过滤器

  • 5、过滤器VS计算属性
    ①computed不能传参,会缓存数据
    ②fliter过滤器可以传参,不会缓存

完毕…有问题留言小编

相关标签: nextTick filter