Vue中this.$nextTick的作用及用法
Vue实现响应式后DOM的变化
data对象中数据改变是如何追踪的?
vue将遍历data对象中所有的属性,并通过Object.defineProperty把这些属性全部转为getter/setter;但是我们是没有办法看到getter/setter的,但是在内部它们让Vue能够追踪依赖,在属性被访问和修改时通知变更。
每个组件都对应一个watcher实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的setter触发时,会通知watcher,从而使它关联的组件重新渲染。
Vue是无法检测到data对象属性的添加和删除
原因:Vue在对初始化组件时会对对象属性执行getter/setter转化,所以属性必须在data对象上存在才能让Vue将它转化为初始化。
varvm=newVue({ data:{ a:1 } }) //`vm.a`是响应式的 vm.b=2 //`vm.b`是非响应式的
如何动态添加根级别的响应式属性【就是对data添加属性】
this.$set(this.someObject,'b',2)
异步更新队列
Vue在更新DOM时是异步执行的。只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
如果同一个watcher被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作是非常重要的。
然后,在下一个的事件循环“tick”中,Vue刷新队列并执行实际(已去重的)工作。
Vue在内部对异步队列尝试使用原生的Promise.then、MutationObserver和setImmediate,如果执行环境不支持,则会采用setTimeout(fn,0)代替。
例如,当你设置vm.someData='newvalue',该组件不会立即重新渲染。
当刷新队列时,组件会在下一个事件循环“tick”中更新。
多数情况我们不需要关心这个过程,但是如果你想基于更新后的DOM状态来做点什么,这就可能会有些棘手。虽然Vue.js通常鼓励开发人员使用“数据驱动”的方式思考,避免直接接触DOM,但是有时我们必须要这么做。为了在数据变化之后等待Vue完成更新DOM,可以在数据变化之后立即使用Vue.nextTick(callback)。这样回调函数将在DOM更新完成后被调用。例如:
{{message}}
在组件内使用vm.$nextTick()实例方法特别方便,因为它不需要全局Vue,并且回调函数中的this将自动绑定到当前的Vue实例上:
Vue.component('example',{
template:'{{message}}',
data:function(){
return{
message:'未更新'
}
},
methods:{
updateMessage:function(){
this.message='已更新'
console.log(this.$el.textContent)//=>'未更新'
this.$nextTick(function(){
console.log(this.$el.textContent)//=>'已更新'
})
}
}
})
因为$nextTick()返回一个Promise对象,所以你可以使用新的ES2017async/await语法完成相同的事情:
methods:{ updateMessage:asyncfunction(){ this.message='已更新' console.log(this.$el.textContent)//=>'未更新' awaitthis.$nextTick() console.log(this.$el.textContent)//=>'已更新' } }
Vue实现响应式并不是数据发生变化之后DOM立即变化,而是按一定的策略进行DOM的更新。
$nextTick是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后使用$nextTick,则可以在回调中获取更新后的DOM
实例化理解Vue响应化
Price:¥{{price}}Total:¥{{price*quantity}}Taxes:¥{{totalPriceWithTax}}
上例中当price发生变化的时候,Vue就知道自己需要做三件事情:
- 更新页面上price的值
- 计算表达式price*quantity的值,更新页面
- 调用totalPriceWithTax函数,更新页面
数据发生变化后,会重新对页面渲染,这就是Vue响应式,那么这一切是怎么做到的呢?
想完成这个过程,我们需要:
- 侦测数据的变化
- 收集视图依赖了哪些数据
- 数据变化时,自动“通知”需要更新的视图部分,并进行更新
对应专业俗语分别是:
- 数据劫持/数据代理
- 依赖收集
- 发布订阅模式
总结
再来回顾下整个过程:
在newVue()后,Vue会调用_init函数进行初始化,也就是init过程,在这个过程Data通过Observer转换成了getter/setter的形式,来对数据追踪变化,当被设置的对象被读取的时候会执行getter函数,而在当被赋值的时候会执行setter函数。
当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到依赖中。
在修改对象的值的时候,会触发对应的setter,setter通知之前依赖收集得到的Dep中的每一个Watcher,告诉它们自己的值改变了,需要重新渲染视图。这时候这些Watcher就会开始调用update来更新视图。
以上就是本次介绍的全部相关知识点内容,如果大家学习中有任何补充可以联系毛票票小编。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。