vue api学习之nextTick的理解

对于 Vue.nextTick 方法,之前没有听说过,突然听到别人提起,貌似作用挺大。以下为学习心得。
官方文档上这样定义:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
看定义就是一头雾水,这定义对于我这种初级选手来说写的也是不明不白。
1、DOM更新循环指的是什么
2、下次更新循环是什么时候
3、修改数据之后使用,是加快了数据更新进度吗
4、在什么情况下用到
带着这些问题去使用一下nextTick
首先写了个demo,按照官方文档的操作过程,试了一下修改数据之后获取更新后DOM的值
<div id="app">
    <div id="div" v-if="showDiv">这是一段文本</div>
    <button @click="getText">获取 div 内容 </button>
</div>
        
        <script type="text/javascript">
            var vm = new Vue({
                el: "#app",
                data:{
                    showDiv:false
                },
                methods: {
                    getText(){
                        this.showDiv = true
                        //修改代码后获取dom的值
                        var text = document.getElementById('div').innerHTML;
                        console.log(text,"text")
                        // this.$nextTick().then(()=>{
                        //     var text1 = document.getElementById('div').innerHTML;
                        //     console.log(text1)
                        // })
                    }
                }
            })
        </script>

果然,浏览器是明智的,报错了

之后改了代码,如上述代码,两个调换一下,把上边的注释掉,下边的代码打开,然后在浏览器中查看,果然能拿到div里的值

在 Vue 的文档中,说明 Vue 是异步执行 DOM 更新的。

查看网上资料,对异步有这样的解释

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

从网上搜了张图片

下面来说一下对这张图的理解

Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新

第一个 tick(图例中第一个步骤,即'本次更新循环'):

  1. 首先修改数据,这是同步任务。同一事件循环的所有的同步任务都在主线程上执行,形成一个执行栈,此时还未涉及 DOM 。
  2. Vue 开启一个异步队列,并缓冲在此事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。

第二个 tick(图例中第二个步骤,即'下次更新循环'):

同步任务执行完毕,开始执行异步 watcher 队列的任务,更新 DOM 。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel 方法,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。

补充一下,在这里我也试了用setTimeout获取div里的内容,确实能获取到

methods: {
                    getText(){
                        this.showDiv = true
                        //修改代码后获取dom的值
                        //var text = document.getElementById('div').innerHTML;
                        //console.log(text,"text")
                        // this.$nextTick().then(()=>{
                        //     var text1 = document.getElementById('div').innerHTML;
                        //     console.log(text1)
                        // })
                        setTimeout(()=>{
                            var text1 = document.getElementById('div').innerHTML;
                             console.log(text1)
                        }, 0)
                    }
                }
                        

也能拿到结果

第三个 tick(图例中第三个步骤):

此时就是文档所说的:下次 DOM 更新循环结束之后。

用途:需要在视图更新之后,基于新的视图进行操作。

原文地址:https://www.cnblogs.com/zmyxixihaha/p/10733461.html