this.$nextTick的那些事

宏任务macro task: setTimeout、MessageChannel、postMessage、setImmediate
微任务micro task: MutationObsever 和 Promise.then

一般情况下微任务优先于宏任务执行;

在 Vue 2.4 之前的版本,nextTick 几乎都是基于 micro task 实现的,但由于 micro task 的执行优先级非常高,在某些场景下它甚至要比事件冒泡还要快,就会导致一些诡异的问题,如 issue #4521、#6690、#6566;但是如果全部都改成 macro task,对一些有重绘和动画的场景也会有性能影响,如 issue #6813。所以最终 nextTick 采取的策略是默认走 micro task,对于一些 DOM 交互事件,如 v-on 绑定的事件回调函数的处理,会强制走 macro task。
作者:ustbhuangyi
链接:https://www.imooc.com/article/21499
来源:Vue.js 升级踩坑小记
本文原创发布于慕课网 ,转载请注明出处,谢谢合作

Vue.js 2.5中$nextTick的MutationObserver 不见了,改成了 MessageChannel 的实现 (MutationObserver是HTML5中的新API,是个用来监视DOM变动的接口。他能监听一个DOM对象上发生的子节点删除、属性修改、文本内容修改等等。)

在 2.5 当中我们引入了一个改动,使得当一个 v-on DOM 事件侦听器触发更新时,会使用 Macrotask 而不是 Microtask 来进行异步缓冲。这原本是为了修正一类浏览器的特殊边际情况导致的 bug 才引入的,但这个改动本身却导致了更多其它的问题。在 2.6 里面我们对于原本的边际情况找到了更简单的 fix,因此这个 Macrotask 的改动也就没有必要了。现在 nextTick 将会统一全部使用 Microtask。
https://zhuanlan.zhihu.com/p/56260917

vue中 $nextTick源码分析 :https://ustbhuangyi.github.io/vue-analysis/reactive/next-tick.html#vue-%E7%9A%84%E5%AE%9E%E7%8E%B0

一、例子1

    
  • {{item}}

上面的运行结果


image.png

当然页面上也正常展示
'a',
'b',
'c',
'我是新增的项目'

这四个内容。

可以看到 mounted里的 this.$el.querySelectorAll('.item').length是3 而不是4,但是我们采用了$nextTick后就正常了;原因是

Vue 是异步执行 DOM 更新,为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。
具体大家可以看这里 https://cn.vuejs.org/v2/guide/reactivity.html#%E5%BC%82%E6%AD%A5%E6%9B%B4%E6%96%B0%E9%98%9F%E5%88%97

二、例子2

前提条件 vue版本 "vue": "^2.5.2",



data(){
return{
        msg: 'Hello Vue.',
        msg1: '',
        msg2: '',
        msg3: '',
        msga: 'Hello Vueaaaa.',
        msg1a: '',
        msg2a: '',
        msg3a: '',
}
},
methods:{
      changeMsg1() {
        this.msg = 'Hello world.';
        this.msg1 = this.$refs.msgDiv.innerHTML
        // Hello Vue   因为vue考虑到性能虽然数据层更新了 ,DOM不会立即更新
        this.$nextTick(() => {
          this.msg2 = this.$refs.msgDiv.innerHTML
          // Hello  world  $nextTick中的函数会在DOM更新完后立即执行 $nextTick 在vue2.5及以后属于宏任务了
        });
        this.msg3 = this.$refs.msgDiv.innerHTML
        // Hello Vue 因为vue考虑到性能虽然数据层更新了 ,DOM不会立即更新
      },
      changeMsg2() {
        this.msg1a = this.$refs.msgDiva.innerHTML
        // Hello Vueaaaa.
        this.$nextTick(() => {
          this.msg2a = this.$refs.msgDiva.innerHTML
          // Hello worlda $nextTick中的函数会在DOM更新完后立即执行 $nextTick 在vue2.5及以后属于宏任务了
        });
        this.msg3a = this.$refs.msgDiva.innerHTML
        // Hello Vueaaaa.
        this.msga = 'Hello worlda';
      },
}

参考例子: https://zhuanlan.zhihu.com/p/26724001

三、应用场景

1、想在created里进行dom操作
2、想dom变化以后进行相应的操作
简单理解Vue中的nextTick

你可能感兴趣的:(this.$nextTick的那些事)