浅谈Vue 性能优化之深挖数组

背景

最近在用 Vue 重构一个历史项目,一个考试系统,题目量很大,所以核心组件的性能成为了关注点。先来两张图看下最核心的组件 Paper 的样式。

 

从图中来看,分为答题区与选择面板区。

稍微对交互逻辑进行下拆解:

  • 答题模式与学习模式可以相互切换,控制正确答案显隐。
  • 单选与判断题直接点击就记录答案正确性,多选是选择答案之后点击确定才能记录正确性。
  • 选择面板则是记录做过的题目的情况,分为六种状态(未做过的,未做过且当前选择的,做错的,做错的且当前选择的,做对的,做对的且当前选择的),用不同的样式去区别。
  • 点击选择面板,答题区能切到对应的题号。

基于以上考虑,我觉得我必须有三个响应式的数据:

  • currentIndex: 当前选中题目的序号。
  • questions:所有题目的信息,是个数组,里面维护了每道题的问题、选项、正确与否等信息。
  • cardData:题目分组的信息,也是个数组,按章节名称对不同的题目进行了分类。

数组每一项数据结构如下:

currentIndex = 0 // 用来标记当前选中题目的索引

questions = [{
  secId: 1, // 所属章节的 id
  tid: 1, // 题目 id
  content: '题目内容' // 题目描述
  type: 1, // 题型,1 ~ 3 (单选,多选,判断)
  options: ['选项1', '选项2', '选项3', '选项4',] // 每个选项的描述
  choose: [1, 2, 4], // 多选——记录用户未提交前的选项
  done: true, // 标记当前题目是否已做
  answerIsTrue: undefined // 标记当前题目的正确与否
}]

cardData = [{
  startIndex: 0, // 用来记录循环该分组数据的起始索引,这个值等于前面数据的长度累加。
  secName: '章节名称',
  secId: '章节id',
  tids: [1, 2, 3, 11] // 该章节下面的所有题目的 id
}]

由于题目可以左右滑动切换,所以我每次从 questions 取了三个数据去渲染,用的是 cube-ui 的 Slide 组件,只要自己根据 this.currentIndex 结合 computed 特性去动态的切割三个数据就行。

这一切都显得很美好,尤其是即将结束了一个历史项目的核心组件的编写之前,心情特别的舒畅。

然而转折点出现在了渲染选择面板样式这一步

代码逻辑很简单,但是发生了让我懵逼的事情。

<div class="card-content">
 <div class="block" v-for="item in cardData" :key="item.secName">
  <div class="sub-title">{{item.secName}}</div>
  <div class="group">
   <span
    @click="cardClick(index + item.startIndex)"
    class="item"
    :class="getItemClass(index + item.startIndex)"
    v-for="(subItem, index) in item.secTids"
    :key="subItem">{{index + item.startIndex + 1}}</span>
  </div>
 </div>
</div>
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/123.html