Vue.nextTick 到底有什么用?

 

Vue 虽然采用了“数据驱动”的思想,但我们依然需要在某些情况下进行少量的 DOM 操作。在 Vue 中,异步执行 DOM 更新。多数情况下,我们并不需要考虑这个过程,但是如果我们的某个操作中,DOM1 的数据变化后,DOM2  需要从 DOM1 的 DOM 结构中获取数据,就会发现数据并没有实时更新,这时候就需要用到  nextTick

 

 

我们都知道大多数情况下 Vue 数据变化后,相应的 html 也随着发生变化。事实上,当数据发生改变后,对应的 html 并没有立即重新渲染,

而是开启一个队列,并将改变的数据缓存在同一事件循环中,当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。

如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。

 

为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。
 

 页面显示如下:

 

但是如果我们把 mounted 钩子改为 created 钩子:

我们发现 DOM 操作失败,页面内容并未更改,在控制台上报错:未找到相应的DOM节点:

 

现在我们给 created 钩子稍作修改,加上 this.$nextTick, 在它的回调函数中写我们的 DOM 操作:

加上 nextTick 后,又可以正常显示:

【分析】:

created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。

 

再来另外一个场景:

我们现在给按钮添加点击事件,事件触发后,相应 DOM 的数据发生更改,并查看此刻该 DOM 节点数据的变化情况:

当我们第一次点击绑定事件的 DOM 后,该按钮的 innerHTML 的文字发生改变,更改为: NEW MESSAGE,但是此时打印该 DOM 所绑定的却是点击之前的旧的数据;

当我们再次点击该元素时,控制台打印的该元素绑定的数据才是新的更改的数据

 

总结:

1.  在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中

2.  在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

posted @ 2020-01-02 17:49  牧羊狼  阅读(1507)  评论(0编辑  收藏  举报