Vue中nextTick()的用法

360 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

对Vue组件数据(props或state)的更改并不会立即在DOM中渲染。因为,Vue异步更新DOM。 我们可以通过使用Vue.nextTick() 或 vm.$nextTick()函数抓住Vue更新DOM的那一刻。让我们详细了解一下这些函数是如何工作的。

1.Vue.nextTick()

Vue从所有组件收集多个虚拟DOM的更新,然后尝试一次性全部更新DOM。例如,让我们看看一个可以切换一个元素的显示与否的组件:

<template>

<div>

<button @click="handleClick">Insert/Remove</button>

<div v-if="show" ref="content">I am an element</div>

</div>

</template>

<script>

export default {

data() {

return {

show: true,

};

},

methods: {

handleClick() {

this.show = !this.show;

console.log(this.show, this.$refs.content);

},

},

};

</script>

试试这个demo

单击“插入/删除”按钮可更改this.show数据,这里使用v-if=“show”指令切换 <div id=“content”>元素的显示与否。

在handleClick内部,控制台中打印的this.show与打印到控制台的this.refs.content不对应。例如,如果this.show的值为true, 然而this.refs.content不对应。例如,如果`this.show`的值为true, 然而 this.refs.content 的值为 undefined(实际上他正确的值应该是( <div data-v-665bb11f="">I am an element</div>):这意味着DOM的渲染与组件的数据是不同步的。
如果你想抓住DOM更新的那一刻,那么你需要使用一个特殊的函数Vue.nextTick(callback)。它在DOM渲染新数据后立即执行回调。 可以让我们找出<div>元素从DOM中插入或移除的时刻:

<template>

<div>

<button @click="handleClick">Insert/Remove</button>

<div v-if="show" ref="content">I am an element</div>

</div>

</template>

<script>

import Vue from "vue";

export default {

data() {

return {

show: true,

};

},

methods: {

handleClick() {

this.show = !this.show;

Vue.nextTick(() => {

console.log(this.show, this.$refs.content);

});

},

},

};

</script>

试试这个demo
打开demo并单击几次“插入/删除”按钮。你会看到这个this.$refs.content (包含<div>元素的引用)和this.show 是完全同步的。

2.this.$nextTick()

也可以在组件实例上的使用this.$nextTick(callback)。 在下面的示例中,handleClick()方法更改了this.show 数据,this.$nextTick()捕捉到了dom更新数据的那一刻。:

<template>

<div>

<button @click="handleClick">Insert/Remove</button>

<div v-if="show" ref="content">I am an element</div>

</div>

</template>

<script>

export default {

data() {

return {

show: true,

};

},

methods: {

handleClick() {

this.show = !this.show;

this.$nextTick(() => {

console.log(this.show, this.$refs.content);

});

},

},

};

</script>

this.$nextTick()使用起来更加的方便。

3.nextTick() with async/await

如果Vue.nextTick() 或 this.$nextTick()调用时不带参数,函数将会返回一个promise,在组件数据DOM更新后得到resolved。 这使得我们可以使用可读性更强的async/await语法。 例如,我们通过使用async/await语法捕获DOM更新,使前面的代码更具可读性:

<template>

<div>

<button @click="handleClick">Insert/Remove</button>

<div v-if="show" ref="content">I am an element</div>

</div>

</template>

<script>

export default {

data() {

return {

show: true,

};

},

methods: {

async handleClick() {

this.show = !this.show;

await this.$nextTick();

console.log(this.show, this.$refs.content);

},

},

};

</script>

试试这个demo

async handleClick(已标记为异步函数。) 当单击“插入/删除”按钮时,this.show 的值会发生变化。 await this.$nextTick() 会等待DOM更新。最后是控制台打印(this.refs.content)引用的实际内容。建议使用以这个async/await语法来使用refs.content)引用的实际内容。 建议使用以这个async/await语法来使用nextTick(),因为它比回调方法更具可读性。

4.总结

更改组件的数据时,Vue会异步更新DOM。 如果希望捕捉组件DOM更新后的那一刻,则需要使用Vue.nextTick(callback)this.$nextTick(callback)函数。 它们的单个回调函数参数将在DOM更新之后立即调用:并且我们将获得与组件数据同步的最新DOM。 或者,如果不传递回调函数作为参数给Vue.nextTick() 或 `this.$nextTick():函数将返回一个promise,该promise将在DOM更新时resolved。 使用async/await语法会使代码比回调方法更具可读性。

译自:dmitripavlutin.com/vue-next-ti…