用法一
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
模版代码:
1 2 3
| Vue.nextTick(() => { alert('数据发生了改变'); }, 1000)
|
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script> </head> <body> <div id="app"> <div>{{ msg }}</div> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data() { return { msg: '改变前' } } }); setTimeout(() => { vm.msg = '改变后'; Vue.nextTick(() => { alert('数据发生了改变'); }, 1000) }) </script> </body> </html>
|
在浏览器运行一下上面的代码,可以看到,页面先显示了改变前,然后弹出一个框,内容为数据发生了改变,这时先不要关掉弹出框,我们看一下页面的内容还是为改变前,当我们把弹出框关掉后,页面的内容显示为改变后。
从例子中我们可以得出:
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。
用法二
从第一节我们可以知道 Vue 是异步执行 DOM 更新的,既然这样,那么Vue.nextTick是不是就可以作为一个Promise使用呢?下面写一段代码试一下。
模版代码:
1 2 3 4
| Vue.nextTick() .then(() => { alert('数据发生了改变'); });
|
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script> </head> <body> <div id="app"> <div>{{ msg }}</div> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data() { return { msg: '改变前' } } }); setTimeout(() => { vm.msg = '改变后'; Vue.nextTick() .then(() => { alert('数据发生了改变'); }); }) </script> </body> </html>
|
在浏览器运行上面的代码,发现和第一节的代码运行结果是一样的。
常用场景
- 在视图更新之后,基于新的视图进行操作。比如在在
created和mounted阶段。created和mounted都是生命周期,这个会在后面提到,现在可以先记一下,加点印象。
- 点击获取元素宽度时会用到,因为我们只要在DOM渲染完成后才能准确获取宽高。