职场上分利器:业务ProCode化之表单篇

268 阅读3分钟

业精于勤荒于嬉 行成于思毁于随

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

经历了九月的休整,又迎来金秋十月更文挑战,前端技术浩繁如海,我也仅仅是初学者一家之言,如有异同,欢迎臧否

来由

我司业务面向的是大量的B端客户,B端客户的业务特点是什么呢?表单字段多,样式要求低,重业务实现,轻页面交互 不同的客户特别是跨行业的客户之间,字段差异极大,但是表单类型相对统一,经过业务沉淀,所以决定采用JSON的形式来组织业务表单的实现。

抽象

要想实现JSON化的表单,首先需要的就是总结提炼共性的属性及方法,经过整理归纳如下:

  • 字段名field及字段描述fieldLabel 要支持自定义【1】
  • 表单类型: 文本、文本域、数字、日期、日期时间、下拉选择【2】
  • 表单项的联动处理【3】
  • 表单项所占据宽度(24栅格布局)【4】

实现 以elementUI为例

  • 最简单的当然就是【1】了,本身elementUI的表单就自带proplabel属性
 <el-form-item
  :prop="item.uniqFieldName"
  :label="item.fieldCustomTitle"
 >
 ...
 </el-form-item>
  • 差不多难度的当然是【4】通过elementUI提供的rowcol组件即可实现一行两个,一行三个,独占一行,一行四个等各种布局。
<el-row :gutter="20">
  <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
</el-row>
  • 表单类型处理,表单类型这里有两种实现,一种是类JSX的语法,通过h函数来实现,一种是通过v-if指令来实现,我个人倾向于v-if指令,主要原因有三点:
    1. h函数相比较JSX语法,还是具有局限性
    1. h函数相比较v-if指令,可读性更差
    1. h函数相比较v-if指令,后期可维护性和扩展性差

综上,我这里采用的是v-if指令的实现方式,组件的属性会设计在以JSON格式交互的模版里

 <el-input
  v-if="item.searchType === 'text'"
  v-model="searchForm[item.uniqFieldName]"
  :placeholder="item.placeholder"
/>
<el-date-picker
  v-else-if="item.searchType === 'datetime'"
  v-model="searchForm[item.uniqFieldName]"
  :type="judgeIsDouble(item)"
  value-format="yyyy-MM-dd HH:mm:ss"
  start-placeholder="开始日期"
  end-placeholder="结束日期"
  :default-time="['00:00:00','23:59:59']"
  align="right"
/>
....
  • 最难的【3】了,表单项的联动处理,这里同样有两个思路:
    1. 通过watch方法去监听form这个model的变化,然后遍历模版配置实现值联动
    1. 通过注册change事件,分别处理每个表单项上所关联的值联动。

这两个方案,看起来方案1会执行更多的无效代码,方案2精准触发,能准确命中要处理的表单项,而实际上,我们的需求可能是这样的: 总价= 单价 x 数量 单价 = 总价 / 数量 数量 = 总价 / 单价 ,这里有可能需要锁定单价或锁定数量。所以,我们需要将方案1和方案2进行结合来使用。

watch: {
form () {
  model.map(k => {
    if (k.computedFunc) {
      this.deal(k.computedFunc)
    }
  })
},
...
methods: {
 onChange (e, item) {
this.deal(item.computedFunc)
}
}

总结

通过模版解析的方式,我们可以将一些通用的表单界面进行封装,并统一处理相同的无关业务逻辑的一些功能,避免每次处理新业务时需要重复编写非业务代码,将关注点更多的聚焦到业务上来,为我们的业务赋能提效。