• 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 更新循环结束之后。

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

  • 相关阅读:
    (水题)洛谷
    (水题)洛谷
    洛谷
    (水题)洛谷
    POJ
    poj 3061(二分 or 尺取法)
    poj 2456(二分)
    poj 1064(二分答案)
    POJ 2559(单调栈)
    STL
  • 原文地址:https://www.cnblogs.com/zmyxixihaha/p/10733461.html
Copyright © 2020-2023  润新知