本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在使用Vue的时候我们能发现,我们在数据里面操作了dom,或者改变了数据,并不能立即同步到真实的dom上,也就是立即改变数据后,我们如果要使用dom上的数据的话,发现还是以前的数据。对此,Vue提供了nextTick的方法,在里面可以拿到dom下次更新后的数据。
我们分三种常见使用场景来看:
在未挂载的时候操作dom:
比如在created和beforeMount中改变dom,因为此时还未挂载,所以其实还没有真实dom,现在改变dom是不生效的。
<body>
<div id="app">
<p id="text">{{msg}}</p>
<button @click="changeHtml">gabian</button>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
msg: "Hello Vue!",
},
beforeMount() {
document.getElementById("text").innerText = "我改变了额!";
},
});
</script>
执行可以发现,改变的数据并没有挂载上去,我们试试用$nextTick;
new Vue({
el: "#app",
data: {
msg: "Hello Vue!",
},
beforeMount() {
this.$nextTick(function () {
document.getElementById("text").innerText = "我改变了额!";
});
},
});
执行结果:
其实在这里,nextTick就是在数据挂载(也就是下次更新)之后才去执行的.
通过下面代码,发现mounted的执行是优先于beforeMount中的$nextTick的。
beforeMount() {
this.$nextTick(function () {
setTimeout(function () {
document.getElementById("text").innerText = "我改变了额!";
},1000)
console.log(document.getElementById("text"),'beforeMount');
});
},
在mounted中使用
mounted钩子执行的时候,所有的dom不一定全部挂载完成,如果要做dom操作最好在nextTick中执行,像异步组件之类的,我找了一个例子。
<div id="app">
<div v-show="status">
<input
ref="inp"
v-model="inputData"
type="text"
placeholder="请输入..."
/>
</div>
</div>
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。
<div id="app">
<p id="text">{{msg}}</p>
<div v-show="status">
<input
ref="inp"
type="text"
v-model="inputData"
placeholder="请输入..."
/>
</div>
<button ref="btn" @click="changeHtml">更改</button>
</div>
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了解不是很多,如果有使用上的错误和补充,欢迎指出。