本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在使用Vue的时候我们能发现,我们在数据里面操作了dom,或者改变了数据,并不能立即同步到真实的dom上,也就是立即改变数据后,我们如果要使用dom上的数据的话,发现还是以前的数据。对此,Vue提供了nextTick的方法,在里面可以拿到dom下次更新后的数据。
我们分三种常见使用场景来看:
### 在未挂载的时候操作dom: 比如在created和beforeMount中改变dom,因为此时还未挂载,所以其实还没有真实dom,现在改变dom是不生效的。
```html
{{msg}}
``` 执行可以发现,改变的数据并没有挂载上去,我们试试用$nextTick;
js new Vue({ el: "#app", data: { msg: "Hello Vue!", }, beforeMount() { this.$nextTick(function () { document.getElementById("text").innerText = "我改变了额!"; }); }, });
执行结果:
其实在这里,nextTick就是在数据挂载(也就是下次更新)之后才去执行的.
通过下面代码,发现mounted的执行是优先于beforeMount中的$nextTick的。
js beforeMount() { this.$nextTick(function () { setTimeout(function () { document.getElementById("text").innerText = "我改变了额!"; },1000) console.log(document.getElementById("text"),'beforeMount'); }); },
### 在mounted中使用
mounted钩子执行的时候,所有的dom不一定全部挂载完成,如果要做dom操作最好在nextTick中执行,像异步组件之类的,我找了一个例子。
```js
new Vue({
el: "#app",
data: {
status: false,
},
mounted() {
this.status = true;
// this.$refs.inp.focus({ cursor: "start" }); // 未生效
this.$nextTick(function () {
this.$refs.inp.focus({ cursor: "start" }); // 生效
});
},
});
``` 像动态组件和异步组件之类的,就可能会出现当你想要操作时还没挂载完成的问题,这个时候对dom的操作就可以使用nextTick去等待他挂载好后执行。
### 数据更新: 这种是最常见的场景,当改变数据的时候,数据更新可能还没有挂载到dom上,但这个时候需要用到改变后的数据时,就可以用nextTick。
```js
{{msg}}
<button ref="btn" @click="changeHtml">更改</button>
new Vue({ el: "#app", data: { msg: "Hello Vue!", inputData: "123456", status: false, }, methods: { changeHtml() { this.inputData = "别输了,最大只能放50个字符..."; console.log(this.$refs.inp.value, 'changeHtml'); // 123456 this.$nextTick(function () { console.log(this.$refs.inp.value, 'changeHtml-nextTick'); //别输了,最大只能放50个字 }); }, }, mounted() { this.status = true; }, beforeUpdate() { console.log(this.$refs.inp.value, 'beforeUpdate'); // 123456 this.$nextTick(function () { console.log(this.$refs.inp.value, "beforeUpdate-nextTick"); //别输了,最大只能放50个字符... }); }, }); ```
这里方法内的$nextTick的回调函数将在update执行完之后执行,执行顺序依次是update、updated里面的nextTick、beforeUpdate里面的nextTick、方法里面的nextTick.
nextTick作用都是在下一次更新后执行里面回调,但是有各种的使用场景,比如之上的,数据更新,数据挂载,数据未挂载时的操作。
对于nextTick了解不是很多,如果有使用上的错误和补充,欢迎指出。