技术

·

7 min read

·

- Views

记录一次做发布功能中遇到问题

Copied

记录一次做发布功能中遇到问题

前言

产品: “做一个小程序展示内容的配置页面,并且我不希望我在页面上每次做更改就立马同步到小程序了,这会影响用户体验,我需要做完CRUD操作后,并点击了发布按钮再将数据同步到小程序”

我们仍认为日活8k的小程序 并不需要考虑这个用户体验问题,但是产品是大佬 battle不过 ^^!。

思路

本着前端能做就尽量前端做的原则(bushi),想了想前端如何实现发布功能。 配置页面操作还是相对简单的,就是一些配置的CRUD+置顶功能。那么能不能维护一个操作队列,有任意操作就将该操作parse为一个数据结构(这里我在想是保存最终状态还是保存delta?)推入队列,最终发布的时候,将操作队列的操作进行一些处理(例如去重,合并对统一数据的同类操作)。最终得到所有数据,再全量传给后端进行更新。但这种思路经不起细想,存在特别多的问题,实现起来也并没这么简单。虽然有点感觉有点类似编辑器中的redo/undo功能,但是我们做业务并不是造轮子,考虑到后端实现的话应该会相对简单一些,所有最终的发布功能还是交给了后端去做(基本思路也是维护两张表,一张表临时操作,一张表是小程序的数据表,发布时再将两张表进行同步,具体是全量同步还是通过diff进行部分更新我就不知道了)。

以为很简单

既然最难的发布功能给了后端做,那前端基本就是搭搭页面了,我以为这个需求将会很简单,没想到还是存在一些问题。

  1. 之前封装的表单基础组件存在一个很奇怪的问题,当我对config中的表单项配置直接进行重新赋值时,虽然渲染确实没问题,但是调用view-design原生的 resetFields 方法此时会失效。
  1. 需要离开这个页面时弹窗提示是否发布更改,点击取消就不离开页面,点击确认就发布并离开页面。但是view-designmenu存在一个问题,点击了menu-item 后,无论路由便没变化,这个menu-item都会变为active状态 也就是说会变为高亮,但是明明menu绑定的activeName属性没有变化。
  1. transition-group渲染的列表中,在经过置顶这类进行顺序替换的操作后,列表数据源list中的item会和item绑定的refs数组的顺序对不上。

一、 resetFields问题

背景

之前基于view-designForm组件封装了一套 通过配置项就能生成表单的基础表单组件(主要是之前代码逻辑太多冗余的了,一个vue文件上千行基本是基操,就想着封装一下减少一下代码量)。基于这个基础组件,又封装了FormModal表单模态框, SearchSection搜索表单这些业务组件,我在海外项目中使用基本功能都是ok的。

原本这个组件是适用于编辑、新增时表单项是相同的,可以支持表单项的一些配置不同,例如disabled这类属性。但是本次使用时,表单项要求不同, 新增时表单项是模板类型 模板ID,而编辑时就只有模板类型

问题

当时思路就是点击编辑时将formItemConfig赋值为editFormItemConfig,新增时赋值为addFormItemConfig

这样确实在编辑和新增时能渲染相应的表单项,但是当我在Modal关闭时调用resetFields发现不生效,这导致我先点编辑,关闭后再新增的话,数据依然存在。

解决

解决这个问题的方法很简单,直接在add时手动将form再置空,但这我觉得很不优雅。

最终通过在新增和编辑时重新设置整个formConfig解决了问题,但我觉得这是比较hack的解决办法,正常来说表单都应该支持动态增减表单项这个功能,如果直接重设formConfig的话,在动态增减表单项时resetFields失效这个问题依然得不到解决。 后续再做做demo研究一下吧,感觉可能还是组件封装存在问题。

二、Menu组件高亮问题

使用Menu组件的时候需要绑定activeName这个属性,该属性表示菜单中高亮的那一个menu-item组件的name属性。 在做点击其他菜单时先提示未保存这个功能时,发现点击某个菜单后即使路由被拦截没有进行跳转,但是菜单高亮项还是会改变。

解决

不要使用view-design自带的高亮样式,自定义一个高亮样式,并且自己通过activeName这个属性来进行判断要不要高亮

三、 Refs中元素顺序与List数据中顺序不一致问题

问题

正常来说我们进行列表渲染并绑定ref后, 肯定是希望typeList[5]的数据对应this.$refs.inputRef[5]这个组件实例。但是我发现当我进行一些置顶操作后,它俩对应不起来了 ???

这可能会存在一些问题,例如我如果希望点击新增后,滚动到滚动区域的顶部,那我如何通过this.$refs.inputRef[0]拿到的并不一定是第一个input元素。虽然可以通过调用滚动区Dom的scrollTo方法来滚到顶部,这里只是举例会存在这个问题以及解决方法。

解决

通过给input设置dataset来解决,

这样我们想要获取第一个input实例只需要