Vue中diff算法详解
Posted AI_huihui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue中diff算法详解相关的知识,希望对你有一定的参考价值。
首先带大家了解一下虚拟DOM概念
一、虚拟DOM本质
虚拟DOM本质就是一个js对象,用来保存DOM关键信息 。
二、虚拟DOM概念
后缀名为 .vue文件中的 template 里写的标签,都是模板,都会被vue处理成虚拟DOM对象来渲染显示在浏览器(真实dom页面)上。
- 内存中生成一样的虚拟DOM结构
项目中的DOM属性有很多个,我们无法很快知道什么属性改变,比如在template中的标签结构为:
相当于<template> <div id='app'> <p class='app_p'>虚拟DOM</p> </div> </template>
const virtualDom = { type:'div', attributes:[{id:'app'}], children:{ type:'p', attributes:[{class:'app_p'}], text:'虚拟DOM' } }
- 当进行vue的数据更新
生成新的虚拟DOM结构
和旧的虚拟DOM结构进行比较
利用diff算法,找出不同,然后更新变化的部分重绘到页面,也叫做打补丁。 - 重绘和回流的概念
回流(重排): 当浏览器必须重新处理和绘制部分或全部页面时,回流就会发生。
重绘: 不影响布局, 只是标签页面发生变化, 重新绘制。
注意: 回流(重排)必引发重绘, 重绘不一定引发回流(重排)。
一、什么是diff算法
diff算法是一个Virtual DOM的加速器,其算法的改进优化是React整个界面渲染的基础和性能的保障,同时也是React源码中最神秘的,最不可思议的部分。vue中,diff算法就是让新虚拟dom, 和旧的虚拟dom相比较。
二、vue中diff算法分析
vue中用diff就是通过同级比较dom树,来进行重绘或者回流。分为三种情况:
-
根元素变了,删除重建整个DOM树
旧虚拟DOM
<div id='app'> <p class='app_p'>虚拟DOM</p> </div>
新虚拟DOM
<div id='app' > <span class='app_p'>虚拟DOM</span> </div>
-
根元素没变,属性改变,更新属性,元素复用
旧虚拟DOM
<div id='app'> <p class='app_p'>虚拟DOM</p> </div>
新虚拟DOM
<div id='app' title='新虚拟DOM'> <p class='app_p'>虚拟DOM</p> </div>
-
根元素和子元素都没变,但元素里的内容改变
没有设置key值
v-for 不会移动DOM,而是复用DOM元素,就地更新<ul id="ul"> <li v-for="item in arr"> {{ item }} <input type="text"> </li> </ul> <button @click="addFn">新增一个</button>
export default { data(){ return { arr: ["小黑", "小黄", "小白"] } }, methods: { addFn(){ this.arr.splice(1, 0, '小绿') } } };
新虚拟DOM会对照旧虚拟DOM来更新,因为只是内容改变,而标签并没有变,所以从第二个标签开始的内容会改变,再增加一个标签更新新的数据对应新的视图。
设有key值
因为新旧虚拟DOM对比,key存在就复用此标签更新内容,如果不存在就直接创建一个新的<ul id="ul"> <li v-for="(item, index) in arr" :key="index"> {{ item }} <input type="text"> </li> </ul> <button @click="addFn">新增一个</button>
v-for先循环产生新的DOM结构, key是连续的,和数据对应然后比较新旧DOM结构,找到区别,打补丁到页面上最后补一个li,然后从第二个往后,都要更新内容。export default { data(){ return { arr: ["小黑", "小黄", "小白"] } }, methods: { addFn(){ this.arr.splice(1, 0, '小绿') } } };
key值只能是唯一不重复的,字符串或数值,新DOM里数据的key存在, 去旧的虚拟DOM结构里找到key标记的标签,复用标签新DOM里数据的key存在,去旧的虚拟DOM结构里没有找到key标签的标签,创建旧DOM结构的key,在新的DOM结构里没有了,则移除key所在的标签。不加key值不影响功能,添加key值可以提高更新性能。
总结 :
-
根元素改变 – 删除当前DOM树重新建
-
根元素未变, 属性改变 – 更新属性
-
根元素未变, 子元素/内容改变
-
无key – 就地更新 / 有key – 按key比较
以上是关于Vue中diff算法详解的主要内容,如果未能解决你的问题,请参考以下文章