vue.nextTick()

380 阅读1分钟

简介

关于异步更新参看之前的文章

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(() => {
            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)

前提:vue2.6版本下,nextTick作为promise被处理

  1. vm.xxx = xxx被当做promise对待,具体处理方式见:juejin.cn/post/688272…

  2. 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