Vue + ElementUI 编辑/新增页面复用总结

前景需求

最近编写简单crm后台管理类项目,涉及到表单的使用上,有着大量的相同内容的表单,根据使用场景分为新建表单编辑表单

实战:实现一个客户等级管理功能,其中包含客户等级列表,新建客户等级,修改客户等级信息功能。 

客户等级列表:

Vue + ElementUI 编辑/新增页面复用总结_第1张图片

新建客户等级:

Vue + ElementUI 编辑/新增页面复用总结_第2张图片

修改客户等级:

Vue + ElementUI 编辑/新增页面复用总结_第3张图片

从上面图中可以看出,客户等级的编辑表单和删除表单基本一致。 

功能实现

实现方式一:



总结:针对客户等级的新建与修改

没有封装,实现一个功能后,另一个功能代码直接复制。开发过程中见过不少人采用这种方式进行开发,这可能是完成功能最快的方式,同时也是带来问题最多的。

  • 不容易维护,复制的代码中如果存在bug,相当于将bug也复制了一份。后续解决bug,或者添加新功能需要花经历修改两处代码。比如:表单需要增加一项出生年月的表单项,需要在添加和编辑的代码中都进行修改。
  • 代码冗余重复率高,常见的代码质量管理的工具中都会包含有重复率一项。
  • … 总之,复制粘贴代码违反了DRY原则:系统的每一个功能都应该有唯一的实现。如果多次遇到同样的问题,就应该抽象出一个共同的解决方法,不要重复开发同样的功能。

方式二:组件封住(封装组件,提取整个弹窗)

定义:客户等级通用表单(levelCommon.vue)



 

 重点备注:父组件,通过props向子组件表单组件传递一些必要的数据(标题、是否显示、model 对象),即实现了新增和编辑功能。

在编辑时,通过传入名为model的props,子组件表单中通过watch的model的变化实现表单的回显。

封住组件调用:



现在,编辑和新建复用了同一个组件。如果需求变更:增加一个出生年月的表单项,之后只需要修改这一个文件,就完成两个功能的修改。

这种实现方式已经可以满足我们目前的需求,但是还是会存在一些问题

  • 不符合单一职责原则:现在表单组件中既封装了表单中的数据和功能,也有操作按钮,Dialog组件的一些数据及操作(如:visible状态),表单组件中通过定义title、visible等props对Dialog所需的props进行了一次中转,产生了一些额外的代码。
    不仅如此,假设现在需要对保存按钮也进行区分:编辑员工时,保存按钮文案改为编辑,或者在新建员工时增加暂存按钮及功能。我们就需要通过增加表单组件的props,或在组件内部进行判断来实现,这里通过增加按钮或修改文案举例,实际上通过slot插槽或其他方式也可以解决这个问题,真实的业务场景可能更为复杂。目的是想说明这些没有涉及到表单功能的修改,但是我们依然需要修改同一个组件。
  • 组件覆盖的场景比较少,在案例中,我们的添加修改都是弹窗的形式,但是在更复杂的真实业务中,可能需要通过一个页面进行添加员工,编辑通过弹窗实现。或者需要实现批量添加员工这样的功能,因为我们的组件内部也集成了Dialog,就没办法很好的完成。

方式三:组件封住(更进一步,剥离Dialog和按钮)

基于对第二种方式出现问题的思考,我们可以对表单组件与Dialog,操作按钮进行剥离,进一步抽象表单组件。

 定义:客户等级通用表单(levelForm.vue)



 

注意:

由于保存按钮现在不在表单组件中了,没办法通过emit的方式对父组件暴露表单数据,所以改为在methods中注册了一个getValue方法,方法中进行了表单验证,通过返回一个Promise的方式,返回表单数据或异常。父组件在使用这个新的表单组件时,通过ref注册一个表单组件的引用,调用表单组件中的getValue方法获取组件内部的数据

封住组件调用:



通过这样封装,当我们需要修改Dialog或者操作按钮,直接在父组件中修改即可。

你可能感兴趣的:(vue,elementui,vue.js,html5)