Vue中this.$nextTick的作用及用法

 更新时间:2020年02月04日 08:31:38   作者:素素  
在本文章里小编给大家整理了关于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将它转化为初始化。

 var vm = new Vue({
 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 = 'new value',该组件不会立即重新渲染。

当刷新队列时,组件会在下一个事件循环“tick”中更新。

多数情况我们不需要关心这个过程,但是如果你想基于更新后的 DOM 状态来做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员使用“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们必须要这么做。为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。例如:

<div id="example">{{message}}</div>
 var vm = new Vue({
  el: '#example',
  data: {
  message: '123'
  }
 })
 vm.message = 'new message' // 更改数据
 vm.$el.textContent === 'new message' // false
 Vue.nextTick(function () {
  vm.$el.textContent === 'new message' // true
 })

在组件内使用 vm.$nextTick() 实例方法特别方便,因为它不需要全局 Vue,并且回调函数中的 this 将自动绑定到当前的 Vue 实例上:

Vue.component('example', {
  template: '<span>{{ message }}</span>',
  data: function () {
  return {
   message: '未更新'
  }
  },
  methods: {
  updateMessage: function () {
   this.message = '已更新'
   console.log(this.$el.textContent) // => '未更新'
   this.$nextTick(function () {
   console.log(this.$el.textContent) // => '已更新'
   })
  }
  }
 })

因为 $nextTick() 返回一个 Promise 对象,所以你可以使用新的 ES2017 async/await 语法完成相同的事情:

methods: {
updateMessage: async function () {

this.message = '已更新'
console.log(this.$el.textContent) // => '未更新'
await this.$nextTick()
console.log(this.$el.textContent) // => '已更新'
}
}

Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。

$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM

实例化理解Vue响应化

<div id="app">

<div>Price :¥{{ price }}</div>
<div>Total:¥{{ price * quantity }}</div>
<div>Taxes: ¥{{ totalPriceWithTax }}</div>
<button @click="changePrice">改变价格</button>
</div>
var app = new Vue({
el: '#app',
data() {

return {
 price: 5.0,
 quantity: 2
};
},
computed: {

totalPriceWithTax() {
 return this.price * this.quantity * 1.03;
}
},
methods: {

changePrice() {
 this.price = 10;
}
}
})

上例中当price 发生变化的时候,Vue就知道自己需要做三件事情:

  • 更新页面上price的值
  • 计算表达式 price*quantity 的值,更新页面
  • 调用totalPriceWithTax 函数,更新页面

数据发生变化后,会重新对页面渲染,这就是Vue响应式,那么这一切是怎么做到的呢?

想完成这个过程,我们需要:

  • 侦测数据的变化
  • 收集视图依赖了哪些数据
  • 数据变化时,自动“通知”需要更新的视图部分,并进行更新

对应专业俗语分别是:

  • 数据劫持 / 数据代理
  • 依赖收集
  • 发布订阅模式

总结

再来回顾下整个过程:

在new Vue()后, Vue 会调用_init函数进行初始化,也就是init 过程,在 这个过程Data通过Observer转换成了getter/setter的形式,来对数据追踪变化,当被设置的对象被读取的时候会执行getter函数,而在当被赋值的时候会执行setter函数。

当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到依赖中。

在修改对象的值的时候,会触发对应的setter,setter通知之前依赖收集得到的 Dep 中的每一个 Watcher,告诉它们自己的值改变了,需要重新渲染视图。这时候这些 Watcher就会开始调用update来更新视图。

以上就是本次介绍的全部相关知识点内容,如果大家学习中有任何补充可以联系脚本之家小编。

相关文章

  • Vue infinite update loop的问题解决

    Vue infinite update loop的问题解决

    这篇文章主要介绍了Vue "...infinite update loop..."的问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • 基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式

    基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式

    本文讲述如何实现拥有酷炫背景视频的登录页面,浏览器窗口随意拉伸,背景视频及前景登录组件均能完美适配,背景视频可始终铺满窗口,前景组件始终居中,视频的内容始终得到最大限度的保留,可以得到最好的视觉效果
    2018-01-01
  • 前端Vue中常用rules校验规则(轮子)如电话身份证邮箱等校验方法例子

    前端Vue中常用rules校验规则(轮子)如电话身份证邮箱等校验方法例子

    当我们在开发应用时经常需要对表单进行校验,以确保用户输入的数据符合预期,这篇文章主要给大家介绍了关于前端Vue中常用rules校验规则(轮子)如电话身份证邮箱等校验方法的相关资料,需要的朋友可以参考下
    2023-12-12
  • vuecli中chainWebpack的常用操作举例

    vuecli中chainWebpack的常用操作举例

    在项目开发中我们难免碰到需要对webpack配置更改的情况,下面这篇文章主要给大家介绍了关于vuecli中chainWebpack的常用操作举例,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • 在vue中安装使用sass的实现方法

    在vue中安装使用sass的实现方法

    这篇文章主要介绍了在vue中安装使用sass的实现方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Vue中响应式系统实现原理图文讲解

    Vue中响应式系统实现原理图文讲解

    Vue的响应式实现是借助Object.defineProperty通过重写getter和setter方法来进行的数据劫持,Vue3通过Proxy代理拦截对象中任意属性的变化,通过Reflect反射对源对象的属性进行操作,然后再在get里收集依赖在set里派发更新
    2023-03-03
  • 富文本编辑器quill.js开发之自定义格式扩展

    富文本编辑器quill.js开发之自定义格式扩展

    这篇文章主要为大家介绍了富文本编辑器quill.js开发之自定义格式扩展,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Vue3配置axios跨域实现过程解析

    Vue3配置axios跨域实现过程解析

    这篇文章主要介绍了Vue3配置axios跨域实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • 加速vue组件渲染之性能优化

    加速vue组件渲染之性能优化

    这篇文章主要介绍了加速vue组件渲染之性能优化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • vue tab切换,解决echartst图表宽度只有100px的问题

    vue tab切换,解决echartst图表宽度只有100px的问题

    这篇文章主要介绍了vue tab切换,解决echartst图表宽度只有100px的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07

最新评论