亲宝软件园·资讯

展开

Vue中this.$nextTick()的具体使用

Litt_White 人气:0

1、官网说法

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

核心点有2个:DOM 更新获取更新后的 DOM

DOM 更新,可以理解为:Vue 的DOM更新机制,那 Vue 的DOM更新机制是什么?

2、DOM 更新

首先,我们要知道:Vue实现响应式并不是数据发生变化之后DOM立即变化,而是异步执行DOM更新的。

通过代码我们验证下:不是数据发生变化之后DOM立即变化

<template>
  <div class="test">
    <div>
      <button @click="test" ref="btn">{{ msg }}</button>
    </div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      msg: '按钮'
    }
  },
  methods: {
    test () {
      this.msg = '信息改变了。。。。'
      console.log('打印结果:' + this.$refs.btn.innerText) // 打印结果:按钮
    }
  }
}
</script>

此时log结果是:打印结果:‘按钮‘。而不是后来的 ‘信息改变了。。。。’
原因:Vue的响应式是异步执行DOM更新

异步执行DOM更新

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

在这里插入图片描述

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
主线程不断执行任务获取任务执行任务……的过程叫做事件循环

简单的理解
vue在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成以后,再进行视图更新.

为什么不同步进行DOM更新呢?
因为如果同步进行DOM更新,则每次对响应式数据进行修改就都会触发setter -> 通知watcher -> 触发re-render -> 生成new vnode(vdom) -> patch(更新真实DOM)。如果每次修改数据都会走一遍这个流程是非常消耗性能的,所以使用异步更新 DOM 的策略,先对数据修改进行整合再使用最终的整合结果一次性对 DOM 进行更新

3、获取更新后的 DOM

<template>
  <div class="test">
    <div>
      <button @click="test" ref="btn">{{ msg1 }}</button>
    </div>
    <div>
      <button @click="test2" ref="btn">{{ msg2 }}</button>
    </div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      msg1: '按钮1',
      msg2: '按钮2'
    }
  },
  methods: {
    test () {
      this.msg1 = '信息改变了。。。。'
      console.log('打印结果:' + this.$refs.btn.innerText) // 打印结果:按钮
    },
    test2 () {
      this.msg2 = '使用this.$nextTick后'
      this.$nextTick(function () {
        console.log('打印结果:' + this.$refs.btn.innerText) // 打印结果:使用this.$nextTick后
      })
    }
  }
}
</script>

通过使用this.$nextTick,此时的打印结果就可以获取到打印结果:使用this.$nextTick后的信息。

4、小结:this.$nextTick()的使用场景

加载全部内容

相关教程
猜你喜欢
用户评论