<template> <div> <span ref="box" @click="updateMessage">{{ message }}</span> </div> </template> <script> export default { name: "page1", data() { return { message: "未更新", }; }, methods: { /* 在方法里直接打印的话, 由于dom元素还没有更新, 因此打印出来的还是未改变之前的值,而通过this.$nextTick()获取到的值为dom更新之后的值 */ /* nextTick返回的是 promise,所以可以结合async/await使用。*/ 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); // => '已更新' }, }, created() { /*可以根据打印的顺序看到,在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作并无作用,而在created()里使用this.$nextTick()可以等待dom生成以后再来获取dom对象*/ /* this.$nextTick()在页面交互,尤其是从后台获取数据后重新生成dom对象之后的操作有很大的优势 */ console.log(this.$refs.box.textContent); // TypeError: Cannot read property 'textContent' of undefined this.$nextTick(() => { console.log(this.$refs.box.textContent); // 未更新 }); }, }; </script>
理论上,我们不应主动去操作DOM,因为Vue的核心思想就是数据驱动DOM,但在很多业务里,我们避免不了会操做一些DOM,这时我们就有可能用到$nextTick