虚拟Dom和Diff算法

虚拟Dom和Diff算法

首先,我们需要了解什么是虚拟Dom,又为什么需要虚拟Dom。虚拟Dom即Virtual Dom,他是用JS对象记录一个Dom节点的副本,当Dom发生更改时候,先用虚拟Dom进行Diff,算出最小差异,然后再修改真实Dom。我们之所以是使用Dom必定是因为他存在一定的优点,在我们用传统的方式操作Dom的时候,我们的浏览器会从构建DOM树开始从头到尾执行一遍过程,效率较低。

	<ul id="aa">
		<li class="a1">我是li1</li>
		<li class="a2">我是li2</li>
		<li class="a3">我是li3</li>
	</ul>

以上面代码为例,按照传统的方式操作Dom我们就需要使用

	var a = document.createElement('li')
	document.querySelector('#aa').appendChild(a)

在js里面输入上面两行代码就会在我们的ul里面追加一个li标签,但是在我们的开发过程中对节点的操作并不少,因此大批量的数据更新会导致浏览器的运行速度减慢,这是使用传统方式的一个弊端,面对这种情况,我们的Vue提供了虚拟Dom。
虚拟Dom就是在我们遇到了数据较大、复杂文档的Dom结构,提供了一种便捷的工具。简单的说,就是我们的虚拟Dom工具的任务就是将虚拟的Dom转换成真是的Dom,当我们的数据发生改变的时候或者页面需要进行重新渲染的时候,会生成一个新的虚拟Dom,使用我们的diff算法,拿我们的新的虚拟Dom和旧的虚拟Dom做对比,找到不一样的地方,将需要更新的地方直接更新,没有更改的地方就无须进行操作。这样我们就可以大量减少真实的Dom操作,提高性能。
下面将通过以下代码来大致了解以下Vue的虚拟Dom:

	<div id="app">
        <my-component></my-component>
    </div>

    <template id="my-component">
        <div id = "vd">
            <ul>您好</ul>
            <ol class = "ol"></ol>
        </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>

        
        // 1.首先,我们需要内存中生成一个虚拟Dom树
        //这是他的内部操作
        // var vD = {
        //     // 标签
        //     tag:"div",
        //     attr:{
        //         id:"vd"
        //     },
        //     children:[
        //         {tag:"ul",content:"你好"},
        //         {tag:"ol",attrs:{className:"ol"}}
        //     ]
        // }


        // 其次,我们将内存中的虚拟dom树初始化渲染成真实dom树
        Vue.component('my-component', {
            template:"#my-component",
            // functional: true,
            // Props 是可选的
            props: {
            // ...
        },
        // 为了弥补缺少的实例
        // 提供第二个参数作为上下文
        })
		// var data = {
		//	arr:[]
		// }

        // 当需要追加一条数据的时候
        // data.arr.push('<li>我是新加进去的</li>')


        // 再将之前的虚拟Dom结合新的数据渲染成一个新的虚拟Dom
        //var newD = {
            // 标签
        //    tag:"div",
        //    attr:{
        //        id:"vd"
        //    },
        //    children:[
        //       {tag:"ul",content:"你好"},
        //       {tag:"ol",attrs:{className:"ol"},children:[
        //           {tag:"li",content:"我是新加进去的"}
        //      ]}
        //   ]
        //  }

        // 使用Diff算法将新生成的Dom树与之前的Dom数进行比较,将对比之后不同的数据进行真实Dom的数据渲染
		
		//实例化对象
        new Vue({
            el:"#app",
            data:{
            }
        })

以上就是我们的虚拟Dom转换成真实的Dom,其实他的渲染在内部是依靠一个叫做render的函数,具体参照文档render
当我们说到虚拟Dom的时候,我们知道我们的新旧Dom树是依靠Diff算法进行对比的,那么什么是Diff算法,他为什么会有这样的功能呢?
Diff算法的作用是用来计算出 Virtual DOM 中被改变的部分,然后针对该部分进行原生DOM操作,而不用重新渲染整个页面。下图是我们的diff算法的对比过程:
diff算法
对比之后将我们的真实Dom渲染在页面上。上图是数据层面的比较,但是当我们的数据结构发生变化的时候,我们需要对它一层一层的进行比较,这个时候我们需要给一个key值,就像我们在电影院买票一样,每张票对应了一个座位,即使我们没有没人来的早,但是那个位置是在我的电影票生效的时候是属于我自己的,当我们需要在同级的结构下面操作,就需要用到key,这样不会取代别的结构的位置。
diff
上图就是将我们的F插入到B和C之间。
我们内部当数据变化,生成一颗新的虚拟dom树,与上一次的虚拟dom树结构进行对比。也就是说,当数据变化的时候,大量操作的是虚拟dom,而虚拟dom属于内存数据,操作起来性能要高的多。而真实的dom操作,只有在追加的那一刻才会进行操作,大大提升了性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值