Mint-ui框架中组件索引值排序混乱bug的解决方案

bug背景

最近接手公司的cordova老项目,项目中用到了f7和mint-ui,其中有一个页面大致是这样的


学生列表

这个首字母列表和右侧的首字母索引是提供的,template代码大致为


    
    
    
        
    

bug表象

1.首先上述template代码使用注释掉的那行,也就是这样:


 
  1. 当上述学生列表为全部的时候,假设右侧索引值对应为 CKW# (其中#为数字或特殊符号)
  2. 增加筛选项,过滤掉部分数据,使右侧索引值变为 C#
  3. 解除筛选项,恢复全部学生列表,右侧索引值 期待 变为 CKW#,实际变成 C#KW

bug解决的过程

WOC!为啥是这样的,一开始以为是自己的compute属性逻辑有bug,然后我一个个打印解除筛选项后的首字母列表,发现一直都是CKW#,并没有发生什么异常,然后我第一想法是diff算法出现了啥猫腻,但是又感觉解释不通,除此之外又无从下手,我抱着侥幸的心理,改了一下v-for的key值:


然后bug没了。。。是的,就是这么简单,用index取代item作为key值,能够修复列表项变动导致的乱序bug

bug产生的原因

我是个不找到问题原因就睡不着觉的白痴,完全无法停止思考。以下是我的思考历程:

  1. 错误的原因分析:
    diff算法和vue原理理论上我掌握的还凑合,但是不能有效的对应实际应用,再加上我没有认真看组件的结构,导致一开始我越思考就离真相越远。。。我甚至觉得,他这和diff没关系,他是通过Vnode的key和组件接收到的首字母进行了一种神秘的排序,才造成这种有实际key值时,新的索引会加在原有索引后面的bug,反之当key和首字母不相等的时候再返回正常的排序。。。我甚至自己模拟出了这种智障排序的实现历程。。。还真能做到!但是这只是个简单的ui组件库啊。。。他的作者真的会想这么多然后刻意地写一个bug吗?

  2. 正确的原因分析:
    肯定是我想歪了,怎么想key对应的最直观的就是diff算法吧,然后冷静分析组件结构!最外层的是个壳子,内层的代表一个首字母对应的Group,然后最里面是自己的列表项。嗯,重点来了。。。右边的索引在哪?因为最外层的组件没有接受首字母相关的参数,我推断索引是的兄弟组件(这里我没看源码),索引是通过操作父组件或者兄弟组件生成的。但是为什么会有这样的bug呢?

对diff算法不了解的同学可以看下我的这篇关于Vue中diff算法的文章,看完了你可能就更不了解了~

产生问题的原因是什么呢?

使用item作为key值,最后由 C#(对应key值为C、#) 变为 CKW#(对应key值为C、K、W、#) 的过程,diff的判断流程是C和C相等,#和K不相等,#和#相等,diff结束,创建节点K,创建节点W,节点的创建顺序是C => # => K => W,CKW#每个对应的都是单独的组件,都会有自己的生命周期,所以他们对索引的添加顺序也会受到diff算法的影响,导致最后的索引变成 C#KW,出现bug

使用index作为key值,最后由 C#(对应key值为0、1) 变为 CKW#(对应key值为0、1、2、3) 的过程,diff的判断流程是C和C相等(0 == 0),#和K相等(1 == 1),diff结束,创建节点W,创建节点#,节点的创建顺序是C => K => W => #,一切又恢复正常。

原理和bug本身都很简单,记录和分享自己成长的历程~

你可能感兴趣的:(Mint-ui框架中组件索引值排序混乱bug的解决方案)