Vue.nextTick()

Vue.nextTick()

首先,我们了解一下Vue的响应式原理,当你把一个普通的 JavaScript 对象传入 Vue 实例作为data选项,Vue 将遍历此对象所有的 property,并使用Object.defineProperty把这些 property 全部转为 getter/setter

这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。

1、举个例子

 

<template>
  <div>
    <div ref="msgDiv">{{msg}}</div>
    <div v-if="msg1">msg1的值:{{msg1}}</div>
    <div v-if="msg2">msg2的值(有nextTick):{{msg2}}</div>
    <div v-if="msg3">msg3的值(区别msg1):{{msg3}}</div>
    <button @click=handleClick></button>
  </div>
</template>

<script>
export default {
  name: 'Hello',
  data () {
    return {
      msg: '原始值',
      msg1: '',
      msg2: '',
      msg3: ''
    }
 },

  methods: {
    handleClick () {
      this.msg = '修改后的值'
      this.msg1 = this.$refs.msgDiv.innerHTML
      this.$nextTick(() => {
        this.msg2 = this.$refs.msgDiv.innerHTML
      })
      this.msg3 = this.$refs.msgDiv.innerHTML
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

 

点击之后的效果:

 从图中可以得知:msg1和msg3显示的内容还是变换之前的,而msg2显示的内容是变换之后的。

2、this.$nextTick()的应用场景

  • 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。created()钩子函数执行的时候,DOM其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。
  • 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

3、async/await的形式

 async handleClick () {
      this.msg = '修改后的值'
      this.msg1 = this.$refs.msgDiv.innerHTML
      await this.$nextTick()
      this.msg2 = this.$refs.msgDiv.innerHTML
      this.msg3 = this.$refs.msgDiv.innerHTML
 }

 

原文地址:https://www.cnblogs.com/lcxcsy/p/13219993.html