Vue中diff算法详解

 首先带大家了解一下虚拟DOM概念 

一、虚拟DOM本质

        虚拟DOM本质就是一个js对象,用来保存DOM关键信息 。

二、虚拟DOM概念

        后缀名为 .vue文件中的 template 里写的标签,都是模板,都会被vue处理成虚拟DOM对象来渲染显示在浏览器(真实dom页面)上。

  1. 内存中生成一样的虚拟DOM结构
            项目中的DOM属性有很多个,我们无法很快知道什么属性改变,比如在template中的标签结构为:
     
    相当于
     
    const virtualDom = {
            type:'div',
            attributes:[{id:'app'}],
            children:{
                type:'p',
                attributes:[{class:'app_p'}],
                text:'虚拟DOM'
            }
    }
  2. 当进行vue的数据更新

    生成新的虚拟DOM结构

    和旧的虚拟DOM结构进行比较

    利用diff算法,找出不同,然后更新变化的部分重绘到页面,也叫做打补丁。Vue中diff算法详解_第1张图片
  3. 重绘和回流的概念
     

    回流(重排): 当浏览器必须重新处理和绘制部分或全部页面时,回流就会发生。

    重绘: 不影响布局, 只是标签页面发生变化, 重新绘制。

    注意: 回流(重排)必引发重绘, 重绘不一定引发回流(重排)。


 一、什么是diff算法

        diff算法是一个Virtual DOM的加速器,其算法的改进优化是React整个界面渲染的基础和性能的保障,同时也是React源码中最神秘的,最不可思议的部分。vue中,diff算法就是让新虚拟dom, 和旧的虚拟dom相比较。

二、vue中diff算法分析

 vue中用diff就是通过同级比较dom树,来进行重绘或者回流。分为三种情况:

  1. 根元素变了,删除重建整个DOM树

    旧虚拟DOM

    虚拟DOM

     新虚拟DOM

    虚拟DOM
  2. 根元素没变,属性改变,更新属性,元素复用

     旧虚拟DOM

    虚拟DOM

     新虚拟DOM

    虚拟DOM

  3. 根元素和子元素都没变,但元素里的内容改变

     没有设置key值
          v-for 不会移动DOM,而是复用DOM元素,就地更新

    • {{ item }}
    export default {
        data(){
            return {
                arr: ["小黑", "小黄", "小白"]
            }
        },
        methods: {
            addFn(){
                this.arr.splice(1, 0, '小绿')
            }
        }
    };

    Vue中diff算法详解_第2张图片

     新虚拟DOM会对照旧虚拟DOM来更新,因为只是内容改变,而标签并没有变,所以从第二个标签开始的内容会改变,再增加一个标签更新新的数据对应新的视图。

    设有key值
        因为新旧虚拟DOM对比,key存在就复用此标签更新内容,如果不存在就直接创建一个新的

    • {{ item }}
    export default {
        data(){
            return {
                arr: ["小黑", "小黄", "小白"]
            }
        },
        methods: {
            addFn(){
                this.arr.splice(1, 0, '小绿')
            }
        }
    };
        v-for先循环产生新的DOM结构, key是连续的,和数据对应然后比较新旧DOM结构,找到区别,打补丁到页面上最后补一个li,然后从第二个往后,都要更新内容。
        key值只能是唯一不重复的,字符串或数值,新DOM里数据的key存在, 去旧的虚拟DOM结构里找到key标记的标签,复用标签新DOM里数据的key存在,去旧的虚拟DOM结构里没有找到key标签的标签,创建旧DOM结构的key,在新的DOM结构里没有了,则移除key所在的标签。不加key值不影响功能,添加key值可以提高更新性能。

总结 :

  • 根元素改变 – 删除当前DOM树重新建

  • 根元素未变, 属性改变 – 更新属性

  • 根元素未变, 子元素/内容改变

  • 无key – 就地更新 / 有key – 按key比较

你可能感兴趣的:(vue,vue.js,算法,javascript,react.js,前端)