diff算法原则

要说diff算法,不能不说虚拟dom,那么,什么是虚拟dom呢?

虚拟dom是用js模拟一颗dom树,放在浏览器内存中,相当于在js和真实dom中加了一个缓存,利用dom difl算法避免了没有必要的dom操作,从而提高性能。

 虚拟DOM  在 VUE.js中,我们使用模板来描述状态与DOM之间的映射关系,vue.js通过编译模板转换成渲染函数(render),执行渲染函数(render)就可以得到一个虚拟节点树,使用这个虚拟节点树就可以渲染页面

 模板——》渲染函数————》vnode————》视图(页面)  

虚拟DOM的最终目标是将虚拟节点(vnode)渲染到视图上,但是如果直接使用虚拟节点覆盖旧节点的话,会有很多不必要的dom操作。  为了避免不必要的DOM操作,虚拟DOM在虚拟节点映射到视图的过程中,将虚拟节点与上一次渲染视图所使用的旧虚拟节点做对比,找到真正需要更新的节点来进行DOM操作,从而避免操作其他无需改动的dom  (diff算法)      

1. 提供与真实DOM节点所对应的虚拟节点 vnode      

2. 将虚拟节点 vnode 和旧虚拟节点 oldVnode 进行对比,然后更新视图

下面到了正题了,diff算法的对比原则:

1、把树按照层级做对比

同一层只和当前层做对比,大人和大人做对比,小孩和小孩做对比

 对比时如果标签一样,会直接在当前标签上修改内容,而不会创建一个新的标签,标签不同会直接删掉然后创建新的标签。

2、同key值对比

3、同组件对比

组件相同会对比着修改,不同直接删除然后创建新的

下面我用代码来帮大家加深一下印象

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			 /*设置列表的样式*/
        .list-item {
         	background: red;
         	color: white;
         	width: 200px;
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
        }
        /*设置列表transition-group的name为list的入场以及离场动画效果*/
        .list-enter-active, .list-leave-active {
            transition: all 1s;
        }
        .list-enter, .list-leave-to
        {
            opacity: 0;
            transform: translateX(-100px);
        }
			
		</style>
	</head>
	<body>
		<div id="app">
		<input type="text" v-model="renwu" name="" id="" value="" />
 
        <button v-on:click="add">添加任务</button>
     
      
      <ul>
      <transition-group name="list" tag="p">
           
            <li v-for="(item,index) in items" :key="index" class="list-item">
              {{ item }}<button @click="remove(index)">删除任务</button>
            </li>
         
        </transition-group>
</ul>
    </div>
	</body>
</html>
	<script src="js/vue.js"></script>
	<script type="text/javascript">
		// 2\. 创建一个Vue的实例
        var vm = new Vue({
            el: '#app',
            data: {
                items: ['任务1','任务2','任务3'],
                renwu:''
            },
            methods:{          
                add(){
                    this.items.push(this.renwu)
                },
                remove(index){
                    this.items.splice(index, 1)
                },
            }
        })
	</script>

大家可以复制下来试一试,这个是个有问题的,我的transtion-group中包裹的li的key我设置的是index,这样大家点击删除按钮后,会发现删是删掉了,但是动画总是在最后一个li上面,这里就可以用diff算法原则来解释了。

同key值对比原则,对比发现前两个是内容被替换了,然后key=2的是节点被删除了,所以删除的动画效果一直是在最后一个li上面。 

只需要把li的key设置为一个唯一的key即可,记住,一定不要在transtion-group中将key设置为index

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值