新闻资讯

新闻资讯 行业动态

vue为什么要异步更新视图

编辑:008     时间:2020-02-25

为什么要异步更新视图

看下面的代码:

<template>
  <div>
    <div>{{test}}</div>
  </div>
</template> 
export default { data () { return { test: 0
        };
    }, mounted () { for(let i = 0; i < 1000; i++) {
        this.test++;
      }
    }
} 

现在有这样的一种情况,mounted的时候test的值会被++循环执行1000次。 每次++时,都会根据响应式触发setter->Dep->Watcher->update->run。 如果这时候没有异步更新视图,那么每次++都会直接操作DOM更新视图,这是非常消耗性能的。 所以Vue实现了一个queue队列,在下一个Tick(或者是当前Tick的微任务阶段)的时候会统一执行queue中Watcher的run。同时,拥有相同id的Watcher不会被重复加入到该queue中去,所以不会执行1000次Watcher的run。最终更新视图只会直接将test对应的DOM的0变成1000。 保证更新视图操作DOM的动作是在当前栈执行完以后下一个Tick(或者是当前Tick的微任务阶段)的时候调用,大大优化了性能。

应用场景

在操作DOM节点无效的时候,就要考虑操作的实际DOM节点是否存在,或者相应的DOM是否被更新完毕。

比如说,在created钩子中涉及DOM节点的操作肯定是无效的,因为此时还没有完成相关DOM的挂载。解决的方法就是在nextTick函数中去处理DOM,这样才能保证DOM被成功挂载而有效操作。

还有就是在数据变化之后要执行某个操作,而这个操作需要使用随数据改变而改变的DOM时,这个操作应该放进Vue.nextTick。

之前在做慕课网音乐webApp的时候关于播放器内核的开发就涉及到了这个问题。下面我把问题简化:

现在我们要实现一个需求是点击按钮变换audio标签的src属性来实现切换歌曲。

<div id="example">
    <audio ref="audio" :src="url"></audio>
    <span ref="url"></span>
    <button @click="changeUrl">click me</button>
</div> 
const musicList = [ 'http://sc1.111ttt.cn:8282/2017/1/11m/11/304112003137.m4a?tflag=1519095601&pin=6cd414115fdb9a950d827487b16b5f97#.mp3', 'http://sc1.111ttt.cn:8282/2017/1/11m/11/304112002493.m4a?tflag=1519095601&pin=6cd414115fdb9a950d827487b16b5f97#.mp3', 'http://sc1.111ttt.cn:8282/2017/1/11m/11/304112004168.m4a?tflag=1519095601&pin=6cd414115fdb9a950d827487b16b5f97#.mp3' ];
var vm = new Vue({
    el: '#example',
    data: {
        index: 0,
        url: '' },
    methods: { changeUrl() {
            this.index = (this.index + 1) % musicList.length
            this.url = musicList[this.index];
            this.$refs.audio.play();
        }
    }
}); 

毫无悬念,这样肯定是会报错的:

Uncaught (in promise) DOMException: The element has no supported sources. 

原因就在于audio.play()是同步的,而这个时候DOM更新是异步的,src属性还没有被更新,结果播放的时候src属性为空,就报错了。

解决办法就是在play的操作加上this.$nextTick()。

this.$nextTick(function() {
    this.$refs.audio.play();
});


原文链接:https://juejin.im/post/5e53f07d51882549036940fc
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐