由于在浏览器中操作DOM的代价是非常“昂贵”的,所以才在Vue引入了Virtual DOM,Virtual DOM是对真实DOM的一种抽象描述。使用virtual DOM渲染页面时,也不会将整个虚拟dom全部渲染。会使用diff算法,计算Virtual DOM树改变部分。
Vue的Diff算法循环比较Virtual DOM同级节点,若找不到与新节点类型相同的节点,则插入一个新节点,若有相同类型的节点则进行节点属性的更新,最后删除新节点列表中不包含的旧节点。
在Diff中会使用到一种就地复用的策略。就地复用是指Vue会尽可能复用之前的DOM,尽可能不发生DOM的移动。同类节点为类型相同且节点数据一致,如前后两个span,span标签上的属性没有改变,但是里面的内容变了,这样就算作同类节点
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input id="username" type="text" placeholder="账号">
</span>
<span v-else>
<label for="password">用户密码</label>
<input id="password" type="text" placeholder="密码">
</span>
<button @click="isUser=!isUser">按钮</button>
</div>
上面代码中label标签和input框都是属于同类节点,点击按钮切换时会复用。input中的已经输入的内容也不会清空。
如上图,输入框中的内容不会清空。
key
vue中有key的话,就会根据key值去判断某个是否修改,重新渲染这一项,对数据改变之后的diff更新比较有很大的性能提升。为了更加高效的更新虚拟dom,另外在vue中使用相同标签元素的过度切换的时候,也需要使用key属性,其目的是为了让vue区分它们,否则vue就只会替换其内部属性而不会触发过度效果。