一文彻底弄懂diff算法的key作用

1,745 阅读3分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

使用index作为key可能会应发的问题?

1、效率问题,页面不会出现展示问题

  • 如果对数据进行逆序添加、删除等破坏顺序操作,会产生没有必要的真实DOM更新,页面效果没有问题,但是效率低下。
  • 我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:

    即把C更新成F,D更新成C,E更新成D,最后再插入E,这样效率不高,且性能不够好。

2、存在输入类DOM,产生错乱数据展示问题

  • 如果DOM结构中还包括输入类(input、textarea)DOM ,会产生错误的DOM更新,界面明显看到问题。
  • 如下图所示,当我们在列表中,在每个输入框中添加对应(数据)内容,逆向添加一个数据,在红色框中的位置,可以看到输入框中的数据产生错乱。

  • 下面我们来分析一下原因
    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。

解决index作为key可能引发的问题

  • 通过唯一标识作为key,则简洁很多
    1)、前四步都一样,从第五步开始节省,查找key=004,发现在旧虚拟DOM并未找到,直接创建新的虚拟DOM;
    2)、后面key=001,002,003...都在旧的虚拟DOM中查询到,则直接使用旧虚拟DOM
    3)、将新的虚拟DOM转化为真实的DOM。

总结: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是没有问题的。