美文网首页
Mint-ui框架中组件索引值排序

Mint-ui框架中组件索引值排序

作者: zpkzpk | 来源:发表于2019-05-07 19:03 被阅读0次

bug背景

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


学生列表

这个首字母列表和右侧的首字母索引是<mt-index-list>提供的,template代码大致为

<mt-index-list :class="{itemRed: hasHeart}">
    <!-- 其中firstLetterArr为首字母列表,firstData为根据首字母区分开的列表项,都是computed中的属性 -->
    <mt-index-section v-for="(letter,indexs) in firstLetterArr" :key="indexs" :index="letter">
    <!-- <mt-index-section v-for="letter in firstLetterArr" :key="letter" :index="letter"> -->
        <in-school-list-item v-for="item in firstData[letter]" :key="item.user_id" :item="item"/>
    </mt-index-section>
</mt-index-list>

bug表象

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

<!-- 基本操作,v-for的key用唯一属性值 -->
 <mt-index-section v-for="letter in firstLetterArr" :key="letter" :index="letter">
  1. 当上述学生列表为全部的时候,假设右侧索引值对应为 CKW# (其中#为数字或特殊符号)
  2. 增加筛选项,过滤掉部分数据,使右侧索引值变为 C#
  3. 解除筛选项,恢复全部学生列表,右侧索引值 期待 变为 CKW#,实际变成 C#KW

bug解决的过程

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

<mt-index-section v-for="(letter,indexs) in firstLetterArr" :key="indexs" :index="letter">

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

bug产生的原因

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

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

  2. 正确的原因分析:
    肯定是我想歪了,怎么想key对应的最直观的就是diff算法吧,然后冷静分析组件结构!最外层的<mt-index-list>是个壳子,内层的<mt-index-section>代表一个首字母对应的Group,然后最里面是自己的列表项<in-school-list-item>。嗯,重点来了。。。右边的索引在哪?因为最外层的组件没有接受首字母相关的参数,我推断索引是<mt-index-section>的兄弟组件(这里我没看源码),索引是通过<mt-index-section>操作父组件或者兄弟组件生成的。但是为什么会有这样的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#每个对应的都是单独的<mt-index-section>组件,都会有自己的生命周期,所以他们对索引的添加顺序也会受到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背景 最近接手公司的cordova老项目,项目中用到了f7和mint-ui,其中有一个页面大致是这样的 这个...

  • 笔记2

    可以在标签中用v-ref:索引名 来绑定索引名可以在组件中用this.$ref.索引名来调用 使用mint-ui,...

  • 索引

    索引用来排序数据以加快搜索和排序操作速度。将一组列值进行排序,得到的就是索引。 从排序后的值中检索需要的数据,就会...

  • Python 数据处理(十一)—— 排序

    11 排序 pandas 支持三种排序方式: 按索引排序 按指定列的值排序 按索引和列排序 11.1 按索引排序 ...

  • Vue和React组件通信的总结

    在现代的三大框架中,其中两个Vue和React框架,组件间传值方式有哪些? 组件间的传值方式 组件的传值场景无外乎...

  • mpvue iview-webapp框架的一些坑

    iview 框架 index 组件在ios 中由于层级关系字母索引被挡住问题 框架代码修改 页面代码

  • mint-ui

    mint-ui 基于vue.js的移动端组件库 安装mint-ui 导入mint-ui包 mint-ui中使用bu...

  • 常见算法

    排序&查找 二分查找 题目:在有序数组中查找一个值,返回该值的索引。(非递归方式&递归方式) 冒泡排序(优化后) ...

  • vue插件总结

    UI组件 框架 element - 饿了么出品的Vue2的web UI工具套件 mint-ui - Vue 2的移...

  • mysql索引浅析

    说到索引,很多人都知道“索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址,在数据...

网友评论

      本文标题:Mint-ui框架中组件索引值排序

      本文链接:https://www.haomeiwen.com/subject/repyoqtx.html