🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 使用index作为key可能会应发的问题? ### 1、效率问题,页面不会出现展示问题 * 如果对数据进行逆序添加、删除等破坏顺序操作,会产生没有必要的真实DOM更新,页面效果没有问题,但是效率低下。 * 我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的: ![](https://img.kancloud.cn/fe/26/fe2662bcff8f46181b21f46bf5ef644a_788x277.png) 即把C更新成F,D更新成C,E更新成D,最后再插入E,这样效率不高,且性能不够好。 ![](https://img.kancloud.cn/f6/d1/f6d100ec63a501081f7a8edfdf1ac143_700x229.png) ### 2、存在输入类DOM,产生错乱数据展示问题 * 如果DOM结构中还包括输入类(input、textarea)DOM ,会产生错误的DOM更新,界面明显看到问题。 * 如下图所示,当我们在列表中,在每个输入框中添加对应(数据)内容,逆向添加一个数据,在红色框中的位置,可以看到输入框中的数据产生错乱。 ![](https://img.kancloud.cn/dd/e5/dde5b89a5b46438ce741d40e67641c3f_370x195.png) ![](https://img.kancloud.cn/cc/96/cc9685426bd087993bb65a4cb6d011a0_390x150.png) * 下面我们来分析一下原因 1)、初始化数据,根据数据生成虚拟DOM,将虚拟DOM转化为展示DOM; 2)、更新数据,向初始数据逆序添加一个数据(老刘-30),生成新数据; 3)、数据变化,生成新的虚拟DOM; 4)、新旧虚拟DOM比较:查找相同key值,如果查询到,存在差异,则以新虚拟DOM替换旧虚拟DOM,反之,则使用久虚拟DOM; 5)、如下图,key=0时,老刘-30与张三-18不等,则替换;input则完全一样,则使用旧虚拟DOM,但是发现没有,key=1,2...每一步都需要替换,(张三、李四、王五都需要新旧替换)效率低下问题出现; 6)、当key=3时,在旧的虚拟DOM中未找到,则创建新的虚拟DOM; 7)、将新的虚拟DOM转化为真实DOM。 ![](https://img.kancloud.cn/ac/d8/acd8b82e82c3d1b3fc3ce8814460e716_1259x707.png) ## 解决index作为key可能引发的问题 * 通过唯一标识作为key,则简洁很多 1)、前四步都一样,从第五步开始节省,查找key=004,发现在旧虚拟DOM并未找到,直接创建新的虚拟DOM; 2)、后面key=001,002,003...都在旧的虚拟DOM中查询到,则直接使用旧虚拟DOM 3)、将新的虚拟DOM转化为真实的DOM。 ![](https://img.kancloud.cn/fa/7d/fa7d40aa228b550b85dca16cd787534b_1455x822.png) ## 总结:key有什么作用(内部原理) ### 1、虚拟DOM中的key作用 * key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue进行新虚拟DOM和旧虚拟DOM的差异比较;比较规则如: 1)、旧虚拟DOM中找到了与新虚拟DOM相同地key:如果虚拟DOM内容没有变化,则直接使用之前的真实DOM;如果虚拟DOM中内容发生改变,则生成新的真实DOM,随后替换掉页面之前的真实DOM; 2)、旧虚拟DOM中未找到与新虚拟DOM相同地key,则创建新的真实DOM,随后渲染到页面。 ## 开发中如何选择key? * 最好使用每条数据的唯一标识作为key,比如id、身份账号、手机号等等; * 如果不存在对数据逆序添加、删除等破坏顺序的操作,仅用于列表展示,使用index作为key是没有问题的。