Fun Guy
Fun Guy
就我的使用来说(Vue)key的作用是为了在数据变化时强制更新组件,以避免“原地复用”带来的副作用。另外,某些情况下**不带key可能性能更好**,见:[issuecomment](https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/1#issuecomment-465847432) 官方文档对于key的描述: [列表渲染-key](https://cn.vuejs.org/v2/guide/list.html#key) | [API-key](https://cn.vuejs.org/v2/api/#key)
@Tarhyru key能提高diff效率其实是不准确的。 见[vue/patch.js](https://github.com/vuejs/vue/blob/dev/src/core/vdom/patch.js#L424),在不带key的情况下,判断[sameVnode](https://github.com/vuejs/vue/blob/dev/src/core/vdom/patch.js#L35)时因为a.key和b.key都是undefined,**对于列表渲染**来说已经可以判断为相同节点然后调用patchVnode了,实际根本不会进入到答主给的else代码,也就无从谈起“带key比不带key时diff算法更高效”了。 然后,官网推荐推荐的使用key,应该理解为“使用唯一id作为key”。因为index作为key,和不带key的效果是一样的。index作为key时,每个列表项的index在变更前后也是一样的,都是直接判断为sameVnode然后复用。 说到底,key的作用就是更新组件时**判断两个节点是否相同**。相同就复用,不相同就删除旧的创建新的。 正是因为带唯一key时每次更新都不能找到可复用的节点,不但要销毁和创建vnode,在DOM里添加移除节点对性能的影响更大。所以会才说“不带key可能性能更好”。看下面这个实验,渲染10w列表项,带唯一key与不带key的时间对比: 不使用key的情况: ``` {{ item.text }} ```  使用id作为key的情况: ``` {{ n.text }} ```  list构造: ``` const list1 = [] const list2 = []...
@Tarhyru 不是的,我是指如果不带key,则a.key 和 b.key 都是undefined,就直接进入两个节点相同的逻辑,到这里diff已经结束了,根本不会运算到后边'利用对象取值而不是遍历数组'找相同节点的那一步。 从这个角度来说,并没有体现“有key比无key diff算法效率更高这一点”。 也不是说楼主的回答是错误的,但仅在于在前面的逻辑中都没有找到相同的节点,才会优先通过keyMap查找,次而通过遍历查找,从这里优化到diff速度。 另外,这道题并非讨论diff速度,而是说key的作用。所以我给出的结论是:key的作用就是更新组件时**判断两个节点是否相同**。相同就复用,不相同就删除旧的创建新的。 @azl397985856 你的补充很好,我提到的“不带key性能更好”,其实是因为两个key都是undefined,自然就相同然后复用组件了,原文有歧义,已做修改。
@Tarhyru 关于遍历节点,实际上不论有没有key,都会遍历节点去找是否有sameVnode,而不是能够像对象取值一样拿到哪个节点需要修改的。你可以看下[这部分代码](https://github.com/vuejs/vue/blob/dev/src/core/vdom/patch.js#L424),首先是while循环判断节点是否相同,只有没找到相同节点时,才会进最后的else,也就是楼主给出的代码,在这里key属性才能优化到查找速度
开源图片接口是境外网站,可能有时候不太稳定