给el-transfer加上联动分页

1,220 阅读6分钟

开发需求

  • el-transfer前端增加分页
  • el-transfer 有左右两个展示列表
  • 左右侧列表,分别加分页控制显示数据条数
  • 并且两边分页切换(页码切换、每页显示条目切换)展示正确的显示

开发要点

1、首先了解el-transfer数据显示特点

  • 右移操作后,左侧的数据保持不变,右侧数据增加右移数据 -> 左侧不再显示右移数据,右侧显示;
  • 如果右移数据不在左侧数据,则右侧不显示;
  • 实行策略:为了后续计算方便,将右移数据从左侧删除,根据分页进行截取,再将右侧展示数据,加回到左侧数据中 例如:
  • 左侧数据 [0,1,2,3,4,5,6,7,8,9]
  • 右侧数据 []
  • 右移 [0,3]
  • 左侧数据 [1,2,4,5,6,7,8,9,0,3]
  • 右侧数据 [0,3]

Untitled Diagram.drawio.png

2、分页联动:

  • 初始分页每页显示条目个数10

  • 当前页初始为1

  • 每一次进行移动(左移或右移),左右列表都要进行重新计算,进行渲染;

  • 左侧分页变动

    • 左侧数据根据当前页,和展示条目数,从移动后的数组中进行计算;
    • 再加上右侧当前页展示的数据;
  • 右侧分页变动

    • 右侧数据当前页,和展示条目数,从右移的数据中截取计算;
    • 重新计算左侧展示;

开发过程

transfer中左右移动数据,两个列表分别进行处理;

左侧列表:

右移:

  • 将选中数据进行记录,存储数据index(总列表中的位置)和值value
  • 同时将数据变化,进行记录,将对位置的数据置为 null
1、要保证右移以后的数据,仍然存在左侧列表

如:

  • [0,1,2,3,4,5,6,7,8,9]
  • 右移 [0,3]
  • 处理数组[null,1,2,null,4,5,6,7,8,9]
  • 左侧数据[1,2,4,5,6,7,8,9]
  • 将右侧数据重新添加到左侧
  • 显示数组 [1,2,4,5,6,7,8,9,0,3]

Untitled Diagram.drawio (1).png

此时显示:左侧显示[1,2,4,5,6,7,8,9];右侧显示[0,3]

2、保证每页显示条目个数10不变

左侧数据只有8个,从9后边的数据,前移的2个数,10,11取弥补空缺

  • 处理数组[null,1,2,null,4,5,6,7,8,9,10,11,12,13...]
  • 排除null[1,2,4,5,6,7,8,9,10,11,12,13...]
  • start 0
  • end 10
  • 截取10条 slice(0,10) -> [1,2,4,5,6,7,8,9,10,11]
  • 再加入右侧数据[0,3]
  • 最终显示数组 [1,2,4,5,6,7,8,9,10,11,0,3]

Untitled Diagram.drawio (2).png

此时显示:左侧显示[1,2,4,5,6,7,8,9,10,11];右侧显示[0,3]

3、分页切换
  • 在右移[0,3]基础上
  • [0,1,2,3,4,5,6,7,8,.....,38]
  • 切换到第三页 currPage = 3
  • start = (currPage - 1) * pageSize = 20
  • end = start + pageSize = 30
  • 处理数组[null,1,2,null,4,5,6,7,8,9,10,11,12,13...20,21,22,23,24,....,28,29,...38]
  • 排除null[1,2,4,5,6,7,8,9,10,11,12,13...20,21,22,23,24,....,28,29,...38]
  • 进行截取slice(20,30)
  • 得到空数组[22,23,24,....,28,29,30,31]
  • 再加入右侧数据[0,3]
  • 显示数组[22,23,24,....,28,29,30,31,0,3]

Untitled Diagram.drawio (3).png

此时显示:第3页,左侧显示[22,23,24,....,28,29,30,31];右侧显示[0,3]

4、边界处理

不是第一页;并且是最后一页;将所有数据向右转移,如何处理 例如:

  • 一共37条数据,
  • [0,1,2,3,4,5,6,7,8,.....,19,20,21,22....35,36]
  • 切换到最后一页
    • currPage 4 pageSize 10
    • start = (currPage - 1) * pageSize = 30
    • end = start + pageSize = 40
  • 显示数据为[32,33,34,35,36,0,3]
  • 将[32,33,...36]全部右移
  • 处理数组[null,1,2,null,4,5,6,7,8,.....,19,20,21,22,31,null,null,null,null,null]
  • 此时显示数组为[],当前页已没有了数据
  • currPage - 1 当前页回退到上一页,重新进行计算,即显示上一页(第3页)数据 Untitled Diagram.drawio (4).png

此时显示:第3页,左侧显示[22,23,24,....,28,29,30,31];右侧显示[0,3,32,33,34,35,36]

左移:

  • {index:1,value:1}
  • 处理数组[0,null,2,3,4,5,6,7,8,9,...]
  • 恢复选中数据,根据存储的index将数据复位;
  • 根据index将value恢复到对应位置,
  • 处理数组[0,1,2,3,4,5,6,7,8,9,...]
  • 再次进行计算,重新渲染

右侧列表:

  • 移动数据,对于左侧数据相对简单
  • 不需要记录数据的下标index,只需要记录value即可 1、右移加入数组,左移从数组中删除;

2、移动操作以后,根据当前分页,要重新渲染右侧列表,保证正确显示;

3、数据截取与左侧列类似,只需要根据当前分页展示;

4、边界处理与右侧列表一致;

考虑左右列表数据之间的影响;

  • 右侧列表切换分页;
  • 并不每次将所有的数据,都添加到左侧列表中;
  • 只需要将右侧当前分页的数据,加到左侧显示数据即可; 例如:
  • 左侧显示数据 [12,13,14,15,16,17,18,19,20,21,0,1,22,23,24,25,26,27,28,29,30,31]
  • 右侧显示数据 [0,1,22,23,24,25,26,27,28,29,30,31]
  • 右侧数据只展示第1页,10条
  • 右侧显示数据 [0,1,22,23,24,25,26,27,28,29]
  • 左侧显示数据 [12,13,14,15,16,17,18,19,20,21,0,1,22,23,24,25,26,27,28,29]

在el-transfer组件的v-model中绑定右侧数据,变量tables

<el-transfer
    v-model="tables"
    :target-order="targetOrder"
    :data="originData"
    :filter-method="filterMethod"
    :titles="titles"
    :filterable="filterable"
    :filter-placeholder="filterPlaceholder"
    @change="tableChange"
  >
  ...
</el-transfer>
const tables = computed({
    get(){
        //右侧展示进行任何变动,都会触发这里
        //在此将右侧当前分页展示的数据,添加到左侧中,进行渲染
        ...
    }
    set(){}
})

至此插件核心处理逻辑分析完毕

总结:

  • 1、数据分离:
    • 将数据分离,每一块的操作都在独立的数组中进行记录,再将数据整合,简单明了;
    • (开始数据没有做分离,所有的操作,展示数据的计算,都在一个数组中进行,比如分页、右移的数据等等,考虑情况复杂,有计算错误和未考虑的情况;)
  • 2、整体框架:
    • 在写整体计算架构时,要将每个大块的计算情况都考虑进来,以方便整体设置架构的编写;
    • (开始只考左侧数据,导致计算到最后,计算的模式越来越复杂,无法适应后边更多的模块的计算;)

后续代码发布github,发包npm...