案例一
场景
A 系统有一个解析简历的功能,后端接口只能解析电话、邮箱,也即接口只返回 phone、email 两个字段。后来接口更新了,支持解析姓名:
后端:简历解析接口更新了,现在会返回多一个字段 name,你前端那边也更新一下吧。 前端:您随便加,接口直接更新就行了,前端不用改。 后端:这么神奇的吗?这是怎么做到的?
那么前端是如何做到接口返回多一个字段,自己却不用修改代码的呢?
分析
原因在于使用了 el-form-renderer
使用了 updateForm
来更新表单值。 updateForm
方法接受一个对象,只要传入对象的 key 与表单的 id 对应上即可更新数据。代码片段如下:
<template>
<el-form-renderer :content="content" ref="form" />
</template>
<script>
export default {
data() {
return {
content: [
{
type: 'input',
id: 'name',
label: '名称'
},
{
type: 'input',
id: 'phone',
label: '电话'
},
{
type: 'input',
id: 'email',
label: '邮箱'
},
// ...
],
}
},
methods: {
async fetch() {
const data = await fetchData() // data: Object
// data 中返回多了一个字段 name,也不需要修改代码
this.$refs.form.updateForm(data)
}
}
}
</script>
所以,即使后端丰富了这个 data
,前端也可以“照吃不误”
如果直接使用 el-form
则无法完成这种操作:你需要手动去更新每个与 el-form-item
绑定的 data
值
<template>
<el-form ref="form" :model="form">
<el-form-item label="名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
form: {
// 每一个表单项需要主动绑定
name: '',
phone: '',
email: '',
},
}
},
methods: {
async fetch() {
const {name} = await fetchData() // data: Object
this.form.phone = data.phone
this.form.email = data.email
// data 中返回多了一个字段 name,需要多写下面一行代码
this.form.name = name
}
}
}
</script>
案例二
场景
B 系统的表单页面比较多,其中不乏带有复杂组件的表单,如下图红框片所示:
直接使用 el-form
开撸,整个页面耦合在一起代码超过 1000 行。
使用 el-form-renderer
后,通过拆分组件,整个页面代码量在 300 行左右,业务组件代码量在 100~300 行之间。
明显能感觉到页面简洁了许多,维护性大大提高。
那么,el-rorm-renderer
是怎么做到精简主页面代码的呢?
分析
秘诀在于 el-form-renderer
支持通过 component
属性渲染自定义组件、在组件内部定义检验规则,提高了拆分页面的可能性。
下面代码示例中,把选择优惠券的表格,抽离成了一个单独的组件。
<!--表单主页面-->
<template>
<el-form-renderer :content="content" ref="form" />
</template>
<script>
import SelectTableList from './select-table-list.vue'
export default {
data() {
return {
content: [
// ...
{
id: 'selectedCoupon',
// 渲染自定义 table 组件
component: SelectTableList,
label: '选择优惠券'
},
// ...
],
}
}
}
</script>
下面是自定义 table 组件示例代码。
<!--自定义 table 组件示例代码-->
<template>
<div class="select-table-list">
<el-button type="primary" size="small" @click="visible = true">选择</el-button>
<el-table :data="selectedList" border></el-table>
<!--
省略一些代码
-->
</div>
</template>
<script>
export default {
name: 'select-table-list',
// 自定义校验规则
rules: [
{
required: true,
message: '自定义组件的提醒消息'
}
],
props: ['value'],
data() {
return {
visible: false,
selectedList: []
}
},
methods: {
confirm() {
const selectedVal = 'table选中的值'
// 更新 value 值,这样 el-form-renderer 可以通过 getFormValue() 拿到该值
this.$emit('input', selectedVal)
this.visible = false
}
}
}
</script>
从上面可以看出,拆分组件后,组件的校验、数据维护都可以进行一个更好的管理,后续调整与改动也只需要关注其组件内部即可。
结语
从上面两个案例可以看出,使用 el-form-renderer
的 好处在于:
- 数据驱动,在主页面只需要关注js,减少 template 的书写
- 数据串联,却又能对各自组件的数据进行单独管理
- 易于把某个复杂功能抽离出来,实现页面的拆分,提高可维护性
- 有利于团队的思想统一,让彼此
review
代码更顺畅
只要去尝试,每个页面都能玩出花来。