zoukankan      html  css  js  c++  java
  • 关于Vue的nextTick的一点小理解

    官方文档表示:为了在数据变化之后等待Vue完成更新DOM,可以在数据变化之后立即执行Vue.$nextTick(callback),这样回调函数就可以在数据变化之后立即执行。

    这段话的意思是:
    例如:存在

    <div id="test">{{ message }}</div>  // 假如此时message的值是 hi
    

    当我们对data(){return{}}中的值进行赋值修改时(例:this.message = 'hello'),虽然数据变化了,但是其实DOM上的内容并未改变,所以如果此时通过原生js获取这个div的innerHTML时,它的值仍是'hi',而不是赋值修改后的'hello'。

    this.message = 'hello';
    console.log(this.message);  // hello, 数据发生了变化
    alert(document.getElementById('test').innerHTML); // hi, DOM还未发生变化
    

    而如果我们在修改了数据之后就想要马上对变化更新后的DOM进行操作,就需要在this.$nextTick(callback)中调用:

    this.message = 'hello';
    console.log(this.message);  // hello, 数据发生了变化
    this.$nextTick(() => {
        alert(document.getElementById('test').innerHTML); // hello, DOM已发生变化
    })
    

    这个例子可能看起来没什么实际用途,另一个例子:
    当我们需要通过某个值(假设: show_login_register)来对显示的内容(是显示登录框还是注册框)进行判断(v-if,v-else),并需要获取变化后的内容的clientHeight来做定位设置,此时,如果我们在show_login_register的值被赋值改变后就直接获取内容的clientHeight,此时,内容还是原来的登录框(假设是想要从登录框变成注册框),如果我们想要获取到变化后的内容(注册框的clientHeight),就需要在this.$nextTick的回调函数中做操作。

    实现原理:
    Vue其实是异步执行DOM更新的。
    1、只要观察到数据变化,Vue将开启一个队列,并对同一事件循环中发生的所有数据变化做缓冲。

    2、如果同一个watcher被多次触发(即一个变量在一次事件循环中被赋值变化了多次),则只会推入队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作非常重要。

    3、然后,在下一个的事件循环"tick"中,Vue刷新队列并执行实际(已去重的)工作(即更新DOM)。

    Vue在内部尝试对异步队列使用原生的Promise.thenMutationObserver(这个是html 5新加的一个功能,其功能是监听dom节点的变动,在所有dom变动完成后,执行回调函数),如果执行环境不支持,会采用setTimeout(fn,0)代替。

  • 相关阅读:
    2013 Multi-University Training Contest 6 部分解题报告
    2013 Multi-University Training Contest 5 部分解题报告
    Codeforces Round #195 (Div. 2) 解题报告
    (转) tarjan算法
    重装SQLServer2008
    关于此博客园及其美化
    矩阵乘法
    CSP-S2019部分题解
    二维偏序
    [BOI2003]团伙
  • 原文地址:https://www.cnblogs.com/limengyi/p/9294551.html
Copyright © 2011-2022 走看看