Appearance
31.说说你对 nextTick 的理解?
当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。
1.Vue2 中的 nextTick
html
<div id="app">{{count}}</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data() {
return { count: 0 };
},
mounted() {
// [渲染watcher,nextTick逻辑,数据更新]
// 按照执行顺序存放到队列中,最后异步执行。
this.$nextTick(() => {
console.log(document.getElementById("app").innerHTML);
});
this.count = 100;
},
});
</script>
<div id="app">{{count}}</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data() {
return { count: 0 };
},
mounted() {
// [渲染watcher,nextTick逻辑,数据更新]
// 按照执行顺序存放到队列中,最后异步执行。
this.$nextTick(() => {
console.log(document.getElementById("app").innerHTML);
});
this.count = 100;
},
});
</script>
Vue2 nextTick 实现原理 优雅降级(Promise、MutationObserver、setImmediate、setTimeout) 这里一般会配合浏览器事件环作为面试题。
2.Vue3 中的 nextTick
html
<div id="app">{{count}}</div>
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
const App = {
el: "#app",
data() {
return { count: 0 };
},
mounted() {
// 当执行mounted之前会创建一个promise,nextTick会被延迟到这个promise之后执行 (值被改为100后再进行渲染)
Vue.nextTick(() => {
console.log(document.getElementById("app").innerHTML);
});
this.count = 100;
},
};
const app = Vue.createApp(App);
app.mount("#app");
</script>
<div id="app">{{count}}</div>
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
const App = {
el: "#app",
data() {
return { count: 0 };
},
mounted() {
// 当执行mounted之前会创建一个promise,nextTick会被延迟到这个promise之后执行 (值被改为100后再进行渲染)
Vue.nextTick(() => {
console.log(document.getElementById("app").innerHTML);
});
this.count = 100;
},
};
const app = Vue.createApp(App);
app.mount("#app");
</script>
Vue3 中不在考虑 promise 的兼容性,所以 nextTick 的实现原理就是 promise.then 方法。