组件名为commonForm,主要是基于element-ui中的表单系列组件进行二次封装,集成了常用的表单功能,组件本身较为简单,主要想推荐前端数据驱动的概念,以及把握开发规范和自定义拓展之间的平衡。
先来看下element-ui官方给出的demo:
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitFn">提交</el-button>
<el-button @click="cancelFn">取消</el-button>
</el-form-item>
</el-form>
其实参照这样的demo去开发也是没问题的,但当开发量大,在开发一个需要长期维护的项目的时候,隐藏在背后的问题就开始浮现了。
首先,统一的规则没有建立,导致后面如果有需求,需要整体修改全站所有表单的时候,就得一个一个页面的去修改,不利于后期的迭代更新和维护。
其次,还是因为统一的规则没有建立,如果是多人开发,可能一个人一个风格,不仅会造成全站模板没统一,并且还是会造成后面的维护困难。或者后续有新人入场,也没办法快速学习代码环境进入开发状态。
所以在开始的时候需要建立统一的数据规范,一方面是为了方便全站开发风格和渲染页面样式统一,并且方便后期维护和更新。另一方面也是希望通过数据来驱动页面,在后面的更新维护中只需要对数据进行操作,便可实现项目的升级改造。
先来看看实际调用的模板:
<commonForm :formData="formData" :formConfig="formConfig"></commonForm>
组件主要包含两个参数:用于保存数据的formData和用于设置表单的formConfig。我们来看看模板和主要规则:
<template>
<div>
<el-form :model="formData" label-width="80px" class="form-box">
<template v-for="formItem in formConfig">
<el-form-item :label="formItem.label" :key="formItem.prop">
<!-- input类型 -->
<el-input v-if="formItem.type === 'input'" v-model="formData[formItem.prop]"></el-input>
<!-- radio类型 -->
<el-radio-group v-if="formItem.type === 'radio'" v-model="formData[formItem.prop]">
<el-radio v-for="optionItem in formItem.options" :label="optionItem.value" :key="optionItem.value">{{optionItem.label}}</el-radio>
</el-radio-group>
<!-- select类型 -->
<el-select v-if="formItem.type === 'select'" v-model="formData[formItem.prop]" @change="formItem.callback(formData[formItem.prop])">
<el-option v-for="optionItem in formItem.options" :label="optionItem.label" :value="optionItem.value" :key="optionItem.value"></el-option>
</el-select>
<!-- 自定义类型 -->
<template v-if="formItem.type==='slot'">
<slot :name="formItem.prop"></slot>
</template>
</el-form-item>
</template>
<el-form-item>
<el-button type="primary" @click="submitFn">提交</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'commonForm',
data() {
return {
}
},
props: ['formData', 'formConfig'],
methods: {
submitFn() {
console.log(this.formData)
},
},
mounted() {}
}
</script>
formConfig: [
{
label: '名称',
prop: 'name',
type: 'input'
},
{
label: '性别',
prop: 'sex',
type: 'radio',
options: [
{
label: '男',
value: 'man'
},
{
label: '女',
value: 'woman'
}
]
},
{
label: '',
prop: "boundary",
type: "slot",
},
{
label: '所在地',
prop: 'location',
type: 'select',
options: [
{
label: '北京',
value: 'beijing',
},
{
label: '上海',
value: 'shanghai',
}
],
callback: (val) => {
console.log(val)
}
},
{
label: "审核",
prop: "check",
type: "slot",
},
]
可以看到组件主要包含四种类型,input,radio,select和自定义的slot类型。统一使用label表示名称,prop表示字段名,type表示表单类型。其中select类型中包含callback字段,是个自定义方法,可以传入参数进行操作。slot类型为自定义类型,用的是vue的具名插槽,可以从父组件传入一些比较特殊的自定义表单或模板。也就是说其中三个是element-ui提供的表单组件,适用于高频率使用的表单类型(当然还可以根据需求添加)。另外一个为自定义类型,可以在表单中插入完全自定义的内容,适用于一些特殊类型的表单或模板,比如在特定位置插入某个内容。
组件调用及渲染效果如下:
<commonForm :formData="formData" :formConfig="formConfig">
<template #boundary>
<div class="form-line">这里是一条分界线</div>
</template>
<template #self>
<el-switch
v-model="formData.check"
active-text="驳回"
inactive-text="通过">
</el-switch>
</template>
</commonForm>
组件到这里结束,只是个简单的例子,主要是想通过这个实例介绍以下两个观点:
1.数据驱动:
组件是个模板,内容还是通过formConfig这个配置数据来进行渲染的,根据几个已定好的规则(label,prop,type)来进行不同内容的渲染。想渲染什么样的表单内容,只需要按照规则修改formConfig就好。这其实就类似虚拟DOM的概念,定义好数据规则和模板,按照规则渲染模板,之后对模板内容的操作,对数据进行更改就好。
2.前端规范化:
首先,常用的几个表单类型,我们通过不同type类型将不同表单添加在组件中。在其中添加了一种slot插槽类型,用于在表单中渲染一些自定义内容。组件中没必要把所有表单类型添加在其中,但也需要提前保留一个插槽,为了插入一些特殊需求的自定义内容,在常用内容和自定义内容之间把握一个平衡。
其次,formConfig中的几个参数也都是统一定义的,标准统一的代码规范,只需要一个文档提前说明规则,就可以方便后期的迭代与维护,有利于多人协作或者工作交接。在其中加入一个callback参数,可以在标准规范中留一个自定义方法,方便对数据进行操作。这也是在标准内容和自定义内容之间把握一个平衡。
文章最后简单总结下数据渲染给我们带来的好处:
1.统一的模板和规范化的数据,方便后期更新维护;
2.标准内容和自定义内容的平衡,按照规则渲染内容的同时保留自定义内容的插槽;
3.后期无论再多的需求,按照规则对数据进行增删改查就好,没问题的。
文章到此结束,希望能给大家带来一点有用之处。