vue中的异步更新
可能你还没有注意到,Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。
上面这段话的意思是:
Vue 实现响应式并不是数据发生变化之后立即更新 DOM,而是按一定的策略进行 DOM 的更新,也就是说延时更新。
当你进行一个赋值操作后,只改变了数据模型,并没有更新视图。
// 修改数据
this.msg = "Hello Vue"
// DOM 还没有更新
this.$nextTick(() => {
// DOM 更新了
})
this.$nextTick
在下次 DOM 更新结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
应用场景
其实就是获取视图更新之后的DOM节点
一、在created生命周期中进行DOM操作
在mounted生命周期才完成渲染挂载,所以在created生命周期是访问不到DOM节点的,如果要在created生命周期操作DOM要在this.$nextTick的回调函数中执行。
1、在created请求完数据后,操作DOM元素渲染Echarts图表
二、在更改数据后,进行节点的DOM操作
修改文本内容,修改节点样式,增删改查等等。
比如用一个数组循环渲染一个列表,在你给数组赋值后,立刻操作列表的某一项,而此时还没有这个节点,所以要在this.$nextTick的回调函数中执行。
1、当在watch中监听弹窗的开关变量,当值为真时,操作弹窗内的DOM元素。此时弹窗还没有渲染完成,所以DOM操作应该放在$nextTick中
2、当弹窗打开后,在弹窗内的一些操作完成后,假如要关闭弹窗,弹窗内的一些操作应该放在$nextTick中(比如路由跳转)
3、面包屑导航,也就是路由跳转,假如点击了面包屑,此时做了一些额外的操作,这些操作应该放在$nextTick中(比如路由跳转,为变量赋值等)
4、图片上传成功后的操作,这些操作应该放在$nextTick中(比如为变量赋值)