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 RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. ......
    UVA 1597 Searching the Web
    UVA 1596 Bug Hunt
    UVA 230 Borrowers
    UVA 221 Urban Elevations
    UVA 814 The Letter Carrier's Rounds
    UVA 207 PGA Tour Prize Money
    UVA 1592 Database
    UVA 540 Team Queue
    UVA 12096 The SetStack Computer
  • 原文地址:https://www.cnblogs.com/rickdiculous/p/15540551.html
Copyright © 2011-2022 走看看