异步更新队列:

首先我们要对vue的数据更新有一定理解: vue是依靠数据驱动视图更新的,该更新的过程是异步的。

即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新队列)。

视图需要等队列中所有数据变化完成之后,再统一进行更新。示例:

<div id="App">
    <input type="button" value="改变文本" @click="change">
    <p ref="myP">{{str}}</p>
</div>
<script>
    new Vue({
        el:"#App",
        data:{
            str:"我之前很瘦的。"
        },
        methods:{
            change(){
                this.str = "现在超胖了!";
                // 输出结果:我之前很瘦的。
                console.log(this.$refs.myP.innerText)
            }
        }
    })
</script>

 

通过以上示例的输出结果可以有力证明:Vue 实现的响应式并不是数据发生变化之后视图立即变化。


获取更新之后的DOM

Vue官方为了避免开发者直接接触视图,鼓励大家以”数据驱动”的方式进行思考。但,现在的我们想基于更新后的视图来搞点事情,该如何下手?

我们可以使用$nextTick(callback)。这里的回调函数(callback)将在数据更新完成,视图更新完毕之后被调用。

更改上个示例中的changeStr方法如下:

    change () {
      this.str = '隐形的翅膀!'
      this.str = '钢铁的翅膀!!'
      this.$nextTick(() => {
          // 输出结果:钢铁的翅膀!!
          console.log(this.$refs.myP.innerText)  
      })
    }    

 

从输出的结果可以看出:我们可以通过$nextTick() 获取到更新之后的DOM

因为 $nextTick() 返回一个 Promise 对象,所以我们也可以使用async/await语法完成相同的事情:

 async change () {
    this.str = '隐形的世邦'
    this.str = '肖邦的翅膀'
    await this.$nextTick()
    console.log(this.$ref.myP.innerText)  
 }

或者

change(){
    this.str = "隐形的翅膀";
    this.$nextTick().then(()=>{
        // 输出结果:腾格尔的翅膀
        console.log(this.$refs.myP.innerText);
    });
    this.str = "腾格尔的翅膀"
}

 


应用场景

1、如果要在created()钩子函数中进行的DOM操作,由于created()钩子函数中还未对DOM进行任何渲染,所以无法直接操作,需要通过$nextTick()来完成。

created () {
    this.$nextTick(()=>{
        this.$refs.myP.innerText = "钢铁的翅膀"
    })
}

 

注:在created()钩子函数中进行的DOM操作,不使用$nextTick()会报错:

//  Error in created hook: "TypeError: Cannot set property 'innerText' of undefined"
created(){
    this.$refs.myP.innerText = "钢铁的翅膀"
}

 

 

版权声明:本文为tffan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/tffan/p/11321140.html