zoukankan      html  css  js  c++  java
  • Vue.nextTick的原理和用途

    this.$nextTick()将回调延迟到下次DOM更新循环之后执行。在修改数据之后立即使用它,然后等待DOM更新。它跟全局方法Vue.nextTick一样,不同的是回调的this自动绑定到调用它的实例上。

    nextTick的由来:由于VUE的数据驱动视图更新,是异步的,即修改数据的当下,视图不会立刻更新,而是等同一事件中的所有数据变化完成之后,再统一进行视图更新。

    nextTick的触发时机:在同一事件循环中的数据变化后,DOM完成更新,立即执行nextTick(callback)内的回调。

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

    以上出现了事件循环的概念,其涉及到JS的运行机制,包括主线程的执行栈、异步队列、异步API、时间循环的写作。大致可以理解为:主线程完成同步环境执行,查询任务队列,提取队首的任务,放入主线程中执行;执行完毕,再重复该操作,该过程称为事件循环。而主线程的每次读取任务队列操作,是一个事件循环的开始。异步callback不可能处在同一事件循环中。

    简单总结事件循环:同步代码执行→查找异步队列,推入执行栈,执行callback[事件循环1]→查找异步队列,推入执行栈,执行callback2[事件循环2]...

    即每个异步callback,最终都会形成自己独立的一个事件循环。

    结合nextTick的由来,可以推出每个事件循环中,nextTick触发的时机:同一事件循环中的代码执行完毕→DOM更新→nextTick callback触发

    ps:上文中的任务队列、消息队列、异步队列指向同一个东西,均指macrotask queue。

    用法:在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。

    • 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中

    created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。

    • 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中


     
     
    为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>nextTick</title>
            <script src="./js/vue.min.js"></script>
        </head>
        <body>
            
            <div class="app">
              <div ref="msgDiv">{{msg}}</div>
              <div v-if="msg1">Message got outside 1 $nextTick: {{msg1}}</div>
              <div v-if="msg2">Message got inside 2 $nextTick: {{msg2}}</div>
              <div v-if="msg3">Message got outside 3 $nextTick: {{msg3}}</div>
              <button @click="changeMsg">
                Change the Message
              </button>
            </div>
            <script>
                new Vue({
                  el: '.app',
                  data: {
                    msg: 'Hello Vue.',
                    msg1: '',
                    msg2: '',
                    msg3: ''
                  },
                  methods: {
                    changeMsg() {
                      this.msg = "Hello world."
                      this.msg1 = this.$refs.msgDiv.innerHTML
                      this.$nextTick(() => {
                        this.msg2 = this.$refs.msgDiv.innerHTML
                      })
                      this.msg3 = this.$refs.msgDiv.innerHTML
                    }
                  }
                })
    
            
            </script>
        </body>
    </html>

    msg1和msg3显示的内容还是变换之前的,而msg2显示的内容是变换之后的。其根本原因是因为Vue中DOM更新是异步的

    需要注意的是,在 created 和 mounted 阶段,如果需要操作渲染后的试图,也要使用 nextTick 方法。

    官方文档说明:

    注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted
     
    mounted: function () {
      this.$nextTick(function () {
        // Code that will run only after the
        // entire view has been rendered
      })
    }


    https://segmentfault.com/a/1190000012861862
    思否参考↑
  • 相关阅读:
    java异常
    Map集和
    获取每个字符出现的次数
    从1-33号球中选取6个红球,且红球数字最多重复不超过3个 从1-16号球中选取一个篮球 由红球和蓝球共同组成一个双色球号码,且红球在左边(按照升序排列),篮球在右边。
    gitlab介绍及使用
    Maven使用介绍
    IDEA集成开发环境安装git,修改代码后文件变色代表的含义
    大数据相关
    开源镜像站汇总
    MySQL配置文件详解
  • 原文地址:https://www.cnblogs.com/rickdiculous/p/15540551.html
Copyright © 2011-2022 走看看