做一个可编辑列表的天花板 (上)

阿弥陀佛

  1. 此文只是将小弟开发中的所得分享给有缘人,希望可以起到抛砖引玉的效果;
  2. 方案环境:Vue(2.6)、Element-UI(2.15)、原生JS

起源:可编辑表格

  该项目运行在特定的客户端系统中,客户端研发部门已经对前端开发中的Vue和Element-UI的进行了二次封装,对前端开发速度有很大的提升。如表格组件,只要给定一个数组对象来配置表头和表格项对应的字段名,再给定数据,就可以渲染出一个表格;

const tableOptinons = [
  { label: "日期", key: "date", width: "180" },
  { label: "姓名", key: "name", width: "180" },
  { label: "地址", key: "address", width: "" },
];

  当业务要求实现表格内容可编辑时,却出现了令人无奈的情况。

现有的方案:成熟稳重

  项目中当前使用的可编辑方案是:新增一个输入框区域,把行的数据映射到该输入框区域,通过操作该区域的输入框来实现对数据的修改;刚开始了解到这个时,觉得难以理解

初步分析:事出反常必有妖

   当我去翻阅这个表格组件时,我确实有些惊讶,因为这个组件既没有插槽接口,而且要结合这个客户端系统,增加了很多操作系统方面的内容。难怪需求提出来的时候,几位技术大佬都摇了摇头。现在反而觉得原方案的实现得巧妙啊,避开了所有的难点,简直是换道超车的典范!其简单又快速,并且稳妥的特点,快速在该部门普及使用。

技术可行性分析:原生JS操作Dom

  但现在业务又提出需求了,要实现可编辑列表。就目前得到的信息来看,若是重写表格组件,则不仅仅要花费大量时间精力来保证该组件在调用和样式上与原组件的高度一致性,并且最花时间的是,要对接该客户端的底层接口。所以重写组件这条路走不了。

  可编辑实现的方向就是将输入框挂载到表格项中

    思路一: 在用户点击了表格项后,将输入框标签作为子标签挂载到该表格项标签中;

    思路二:修改全部的表格项:用生成的输入框Dom节点去代替原表格项Dom节点;

  这两种的实现可以在表格组件生成后,用原生JS直接修改Dom节点。技术上是可行的。 

深入需求分析:隐性需求

  接着还是对需求和实际业务的进一步分析,毕竟林子大了,什么鸟都有。在收集了各方面的信息后,发现对性能的需求确实是隐藏其中的。因为在该项目中,小弟见过最大的一个数据是对发票信息的修改,其中有发票号和发票日期这两列字段需要编辑,而且数组高达两百条;在这种不使用虚拟列表的情况下,光是两百个日期组件这种大型组件,就已经很耗时间和内存了;每次加载这个页面来都需要至少十多秒才会停止转圈圈。但情况不仅仅限于首次渲染页面,在diff新旧节点,也有很大消耗。所以思路二不是优选方案。但思路一,其用户体验不佳,特别是文本输入框,有时就想直接点击在第二行或者第五个字那进行修改,但要点击两次,在输入框挂载后再点一次才能选中要修改的地方,太顿挫了,而优点就是需要渲染的组件少,并每种类型的输入框只要生成一个就可以,所以时间和内存的消耗都非常理想;

  另外要实现的编辑框类型,已知的需求有:文本框、下拉框、日期选择器、金额输入;另外得考虑到后期可能扩展其他类型

  总的来说:表格数据会出现比较大的情况,要关注性能要求;文本框用户体验上的原因不能在点击后才挂载编辑框;编辑框类型要考虑扩展性

确定总体设计:智能虚拟编辑框

  这两个思路总的来说:一个是用户体验好,性能差;另一个是性能好,用户体验差。赶工期的话,可以选中一个着手实现。

  因为这两种思路都不理想,同时没有明确的交付日期,也不是分配到小弟手上的任务。所以暂时挂起,去忙其他。直到那天午后,岭南的木棉花,和缠绵的雨,在三月结伴同行,相约翩翩起舞。不如把思路一和二也结合起来用:

    1. 组件本身比较小的或者对用户体验有明显影响的,如文本输入框类型;直接挂载在表格项节点;
    2. 组件本身比较大的,则采用思路一,在点击时,挂载在表格项中,同时使用虚拟编辑框;

      如 表格项使用日期选择器的图标,在视觉上如同渲染了一个日期选择器;  因为日期选择器本身就是需要点击时才展开,在挂载时执行展开的相关方法,在视觉上并没有延迟感,并且使用时没有顿挫感;

     3. 支持自定义:虚拟编辑框和实际编辑框; 提供相关接口,以扩展可编辑表格的使用范围;

规划详细设计:拆解后再组合

  这套方案在性能和使用感上都接近完美,但是代码实现上要花很多时间和精力;

  得花一番功夫规划好详细的编码设计,再去实施编码阶段。

拆解:一步一步来走
    1. 根据用户使用流程,把编程工作分成了先后三部分来实现:虚拟编辑框、挂载编辑框、数据修改。
    2. 根据该功能的编码实现流程,分成三步走:先实现一个使用select下拉框场景的,再实现其它类型的,最后以暴露相关接口和钩子函数来应对特殊场景;
组合:掌握对整体的把控
    1. 抽象接口:首先是虚拟编辑框的接口,再是创建组件的接口,最后是点击时,挂载组件和修改数据的接口;
    2. 存在多种编辑框类型,可以通过策略模式来管理;
    3. 不同编辑框的事件和props则可以通过适配器模式来统一接口和数据;
    4. 表格项的点击处理用中介模式来改变网状式的多对多的关系,变成相对简单的一对多,新增编辑框类型或者其他点击事件,只需要增加中介层对应的通讯控制就行;由中介控制器来决定是否启动挂载编辑框,编辑框是否延迟创建,和挂载异常处理;
    5. 尽量借用Vue和Element-UI已经有的功能和属性,使得不增加新组件的学习成本和研发成本,更是可以尽量减少代码量,减少出错率
    6. 编码实施中,尽量遵循单一职责、高颗粒度、纯组件等来实施

编程实施与测试:坚持就是胜利

  编码阶段实在一言难尽,不仅仅有来自对Vue和Element-UI的理解和掌握,更多的是对前端三驾马车的考验。

  期间反复推倒重建次数不下十次,更是进行四次大版本的更新迭代、从简单的完成任务,到全面优化、再到全面简化;内存和时间消耗都从O(n)降到O(1),至少下降了30%。

  所幸前面的分析和设计确实做足了功课。( 现在还记得论文答辩时,老师只提了句:你的项目设计写在需求分析前面?;而后在工作中更是被各种业务需求补足了功课 )

  方向对了,总不至于南辕北辙,只是走得快走得慢的问题,剩下的就是坚持。

    做一个可编辑列表的天花板 (下):编程实施与测试:坚持就是胜利    

 阿弥陀佛

 

posted @ 2024-04-14 10:18  妙9999  阅读(9)  评论(0编辑  收藏  举报