简介
关于异步更新参看之前的文章:https://www.jianshu.com/p/9831e1df191c
vue.nextTick()执行顺序问题
原谅我看不懂原理和源码,只能暴力自测了,采用最原始的归纳法......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https:cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="example"></div>
<script>
var vm = new Vue({
el: '#example',
data: {
message: '111'
},
beforeMount() {
console.log("beforeMount");
},
mounted() {
console.log("mounted");
},
beforeUpdate() {
console.log("beforeUpdate");
},
updated() {
console.log("updated");
},
render: function (createElement, context) {
console.log("render");
return createElement(
'div',
{},
[this.message]
);
}
})
setTimeout(() => {
console.log("setTimeout");
}, 0)
Promise.resolve().then(value => {
console.log("Promise1", vm.$el.textContent);
Vue.nextTick(() => {
vm.message = '555'
Vue.nextTick(() => {
console.log("promise1==InNextTick===", vm.$el.textContent);
})
console.log("promise1==nextTick===", vm.$el.textContent);
})
})
Vue.nextTick(() => {
console.log("topnextTick===", vm.$el.textContent);
})
vm.message = '222' // 更改数据
Promise.resolve().then(value => {
console.log("Promise2", vm.$el.textContent);
Vue.nextTick(() => {
console.log("promise2==nextTick===", vm.$el.textContent);
})
})
Vue.nextTick(() => {
// vm.message = '555'
Vue.nextTick(() => {
console.log("bottomInnerNextTick===", vm.$el.textContent);
})
console.log("bottomnextTick===", vm.$el.textContent);
})
vm.message = '333' // 更改数据
Promise.resolve().then(value => {
console.log("Promise3", vm.$el.textContent);
})
console.log(vm.$el.textContent);
vm.message = '444'
</script>
</body>
</html>
总结
前提:vue2.6版本下,nextTick作为promise被处理
- vm.xxx = xxx被当做promise对待,具体处理方式见:https://juejin.im/post/6882727213708345352
- vm.xxx = xxx会触发updated更新,更新之后第一时间会执行当前微任务队列中的nextTick
// 比如微任务队列内容是:vm.xx=xxx、p1(p1-nextTick)、p2、nextTick1、p3、nextTick2.
p1(p1-nextTick):表示p1这个promise回调中还包含一个nextTick
p2:表示p2是promise回调
nextTick1:是个nextTick回调
p3:表示p3是promise回调
nextTick2:是个nextTick回调
此时按照顺序执行`vm.xx=xxx`,触发beforeUpdate、render、updated,这时候接着执行nextTick1回调,然后执行nextTick2回调,然后再执行p1回调,并将p1回调中的p1-nextTick添加到微任务队列的末端,也就是p3的后面,这时候再执行p2,执行p3,然后执行p1-nextTick