一.代码的理解
<template>
<div id="app">
<div>
</div>
<button @click="fn" ref="box"> {{ name }}</button>
</div>
</template>
<script>
export default {
data: function () {
return {
name: "张三",
};
},
mounted(){
},
methods:{
fn(){
this.name="李四"
console.log(this.$refs.box.innerHTML);
},
},
name: "App",
components: {},
};
</script>
<style></style>
这些代码大家可以看下,template模版双向绑定的是张三这个对象,页面上显示的也是:
在点击按钮之后发生更改,将张三这个对象-------------------李四;
可以看出视图上发生了更改,张三变成了李四。
但是打印出来的DOM还是张三,这是为什么呢?
通过查阅资料,大概知道了些,通过Watcher收集页面中的数据状态变化,当状态发生改变的时候,收集页面的状态变化,如果状态改变一次就去更新一次DOM,这样是极大程度上浪费的一种表现,那么怎么样才能解决这个问题呢,我认为的是等状态全部更新完毕,收集完毕之后,在去使用模版的渲染方式,去完成页面的渲染,来达到最优的效果,因为DOM的渲染是异步的,在这个过程中是在任务队列中执行的,JS是一个单线程的语言,同步任务直接在主线程中就执行了,遇到异步任务我们不可能去等任务执行完在执行下一行:
1.DOM1的渲染添加到任务队列
2.DOM2的渲染添加到任务队列
主线程的任务执行完毕后,执行任务队列中的异步任务,也就是DOM的渲染。
但是在这个过程中,我们要等待所有的DOM都添加到任务队列中,所以这个时候不去执行,而是等到下个周期任务队列查找的时候去执行,至于下个周期是什么时候,我认为可能就是另外一个页面开始执行的时候,因此我们获得到的DOM是属于上次更新的,并不是更新完之后的DOM,所以上面的例子就可以看出,我们将张三----->李四的时候,去打印他的DOM任然是张三。
如果想要获取李四怎么办:
fn() {
this.name = "李四";
this.$nextTick(() => {
console.log(this.$refs.box.innerHTML);
});
我们可以使用,vue提供的一个api,$nextTick,以回调函数的形式来获取,更新完之后的DOM,
二.应用方面
上述的问题我们讲了,DOM的更新是异步的,这个时候我们在做大屏可视化的时候,有些地方是要获取实时的DOM的,这个时候就可以利用这个APi,完成视图的渲染,如果要获取实时的DOM都可以应用这个API。