v-for中的key

2020-09-08  本文已影响0人  _西风凋碧树

大家要知道,不仅只是vue中,react中在执行列表渲染时也会要求给每个组件添加key这个属性
如果想知道key的作用,不得我们得聊一下虚拟DOM的Diff算法

所谓虚拟DOM的诞生,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法,它的核心是基于两个简单的假设:

  1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构
  2. 同一个层级的一组节点,他们可以通过唯一的id进行区分

当页面的数据发生变化时,Diff算法只会比较同一层级的节点:

如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了
如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新

当某一层有很多相同的界定啊时,也就是列表节点,Diff算法的更新过程默认情况下也是遵循以上原则

既把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?

所有我们需要使用key来给每个节点做一个唯一的标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点

所以一句话,key的作用主要是为了高效的更新虚拟DOM。另外vue的在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分他们,否则vue只会替换其内部属性而不会触发过渡效果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
        
        .userList{
            border: 1px solid red;
            margin: 20px 0;
            padding: 10px 10px;
        }
    </style>
</head>
<body>
    <div id="app"></div>
    <script type="text/javascript" src="vue.js"></script>
    <script src="lodash.min.js"></script>
    <script type="text/javascript">
        Vue.component('my-com',{
            template:`
                 <div class = 'userList'>
                    <div class = 'content'>
                        <h3>{{obj.name}}</h3>
                        <p>{{obj.content}}</p>
                    </div>
                    <div class ='control'>
                        <input type="text" placeholder = '请输入你的名字' />
                    </div>

                </div>
            `,
            props:{
                obj:Object
            }
        })
        

        var App = {
            data(){
                return {
                    datas:[
                        {id:1,name:'张三',content:'我是张三'},
                        {id:2,name:'李四',content:'我是李四'},
                        {id:3,name:'王五',content:'我是王五'}
                    ]
                }
            },
            template:`
                <div>   
                    <button @click = 'change'>改变顺序</button>
                    
                    <my-com v-for = '(item,index) in datas' :obj = 'item' :key = 'item.id'></my-com>

                </div>
            `,
            methods:{
                change(){
                    console.log(1);
                    this.datas = _.shuffle(this.datas);
                }
            }
        };

        new Vue({
            el:'#app',
            components:{
                App
            },
            template:`<App />`
        });
    </script>
    
</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读