Vue 中 $nextTick() 的应用

匿名 (未验证) 提交于 2019-12-02 23:56:01

Vue 在更新 DOM 时是异步执行的。

只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。

<!DOCTYPE html> <html>  <head>     <meta charset="utf-8">     <title>Vue nextTick</title>     <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script> </head>  <body>     <div id="app">         <example></example>     </div>      <script>         // 注册 example 组件         Vue.component('example', {             template: '<span ref="box" @click="updateMessage">{{ message }}</span>',             data () {                 return {                     message: '未更新'                 }             },             methods: {                 updateMessage () {                     this.message = '已更新'                                          console.log('nextTick方法前--->', this.$refs.box.textContent) // => '未更新'                      this.$nextTick(function () {                         console.log('nextTick方法内--->', this.$refs.box.textContent) // => '已更新'                     })                      console.log('nextTick方法后--->', this.$refs.box.textContent) // => '未更新'                 }             }         })          // 创建根实例         new Vue({             el: '#app'         })     </script> </body>  </html>

点击 span , 执行 updateMessage方法,输出结果如下:

nextTick方法前---> 未更新 nextTick方法后---> 未更新 nextTick方法内---> 已更新

可见,Vue 数据发生变化之后,视图不会立即变化。该更新过程是异步的。

所以,如果要获取更新后的视图,可以使用 $nextTick(callback)。这里的回调函数(callback)将在数据更新完成,视图更新完毕之后被调用。

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

methods: {     async updateMessage () {         this.message = '已更新'         console.log('nextTick方法前--->', this.$refs.box.textContent) // => '未更新'          await this.$nextTick(function () {             console.log('nextTick方法内--->', this.$refs.box.textContent) // => '已更新'         })          console.log('nextTick方法后--->', this.$refs.box.textContent) // => '已更新'     } }

执行点击事件,打印结果:

nextTick方法前---> 未更新 nextTick方法内---> 已更新 nextTick方法后---> 已更新

在Vue生命周期钩子函数created()中进行的DOM操作。

由于created()钩子函数中还未对DOM进行任何渲染,所以无法直接操作,需要通过$nextTick()回调来完成。

created() {     console.log(this.$refs.box.textContent);  // TypeError: Cannot read property 'textContent' of undefined     this.$nextTick(() => {         console.log(this.$refs.box.textContent);  // 未更新     }) },
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!