问题:Vue/React中绑定的key是什么?有什么作用?
key是虚拟DOM对象的标识,在数据的更新显示中起到非常重要的作用。
当页面中的数据发生变化时,react会根据“新数据”生成“新的DOM”,但是当数据只有部分发生变化时,React是否会一次性更新页面中的所有DOM呢?
答案是否定的。那么React又是如何辨别哪些是重复DOM,哪些是“新的DOM”呢?
此时利用的就是这个key值了。
实现过程:
若在旧虚拟DOM找到了与新虚拟DOM中相同的key:
(1)若虚拟DOM中内容没变,则直接使用之前的真实DOM
(2)若虚拟DOM中内容变了,则生成新的真实DOM,替换掉页面中真实的DOM
若在旧虚拟DOM中没找到与新虚拟DOM中相同的key:
则根据数据创建新的真实DOM,然后渲染到页面上
使用index作为key可能出现的一些问题:
在程序中最好使用唯一的id标识作为key,可以避免以下的问题
若对数据进行逆序操作时,比如在数组的前面插入一个数据,此时,若使用index作为key,则新插入数据的key值为0,原先的数据key值都发生了变化(在原先的基础上+1),根据diffing算法,所有的DOM都需要重新渲染,但是页面上行真正发生变化的其实只有新添加的数据,导致产生了没有必要的的真实DOM的更新,影响效率问题
<!-- 初始数据 -->
[
{id:1, name:'Tom'},
{id:2, name:'Jerry'}
]
<!-- 初始的虚拟DOM -->
<li key=0>Tom<input type="text" /></li>
<li key=1>Jerry<input type="text" /></li>
<!-- 向数组前插入一条数据 -->
[
{id:0, name:'Bob'},
{id:1, name:'Tom'},
{id:2, name:'Jerry'}
]
<li key=0>Bob<input type="text" /></li>
<li key=1>Tom<input type="text" /></li>
<li key=2>Jerry<input type="text" /></li>
<!-- 此时真正的新数据其实只有Bob,但是由于key全部改变,
则整个数据重新渲染 -->
上面导致的问题不仅仅是数据全部的重新渲染,还导致了另一个更为严重的问题,由于在结构中还包含了输入类的DOM,会导致界面出现问题。原来input标签并不会重新渲染,若原先input输入框中有对应的name,那么会在数据重新插入后,导致“错位”
<!-- 原先 -->
<li key=0>Tom————输入框中为Tom</li>
<li key=1>Jerry————输入框中为Jerry</li>
<!-- 更新后 -->
<li key=0>Bob————输入框中为Tom</li>
<li key=1>Tom————输入框中为Jerry</li>
<li key=2>Jerry————<input type="text" /></li>
<!-- 页面结构混乱 -->
注意:
如果不存在对数据的逆序添加、删除等破坏顺序操作,仅仅是用于渲染数据展示,那么使用index作为key是没有问题的