Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第67题:谈一谈你对 nextTick 的理解? #67

Open
noxussj opened this issue Jun 18, 2020 · 0 comments
Open

第67题:谈一谈你对 nextTick 的理解? #67

noxussj opened this issue Jun 18, 2020 · 0 comments

Comments

@noxussj
Copy link
Owner

noxussj commented Jun 18, 2020

查阅了网上一些资料后,以下内容为个人理解,如果不对的地方还请大神指导

什么是nextTick呢?

nextTick,我可以理解为next是下一个的意思,在事件循环中,每进行一次循环操作称为 tick
就是下一个事件循环操作,也就是下一个宏任务

nextTick实现原理

因为目前浏览器平台并没有实现 nextTick 方法,所以 Vue.js 源码中分别用 Promise、setTimeout等方式在 microtask(或是task)中创建一个事件,目的是在当前调用栈执行完毕以后(不一定立即)才会去执行这个事件

直接上代码看效果

<template>
    <div class="views__home">
        <div ref="xiaoming">{{message}}</div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            message: 'test'
        };
    },
    mounted() {
        this.message = 'xiaoming';

        console.log('first', this.$refs.xiaoming.innerHTML);

        this.$nextTick(() => {
            console.log('second', this.$refs.xiaoming.innerHTML);
        });
    }
};
</script>

image

为什么会这样呢?
当你执行this.message = 'xiaoming'的时候,只是把xiaoming赋值给了一个变量,dom实际上还没有更新呢

那么为什么在this.$nextTick里面却可以拿到dom更新后的值呢?
一般来说nextTick,就是在dom渲染完了之后才会执行

我们要知道vue里面有一个虚拟dom,页面上所有的操作都是先改变虚拟dom,最后再把虚拟dom更新到实际的页面dom上,这个时候就会涉及到到一个问题,什么时候才是最后?
这个时候就会涉及到JS事件执行机制中的宏任务和微任务

个人理解的步骤应该是这样的,如果有错的地方还请大神指导

  1. 执行完当前宏任务script,立即执行微任务
  2. 微任务执行完毕后进行页面渲染
  3. 页面渲染完毕,开始执行$nextTick

参考资料
谈一谈 nextTick 的原理

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant