Vue2+ElementUI表单、Form组件的封装 :引言
在 Vue2 项目中,ElementUI 的 el-form
组件是常用的表单组件。它提供了丰富的功能和样式,可以满足各种需求。但是,在实际开发中,我们经常会遇到一些重复性的需求,比如:
- 需要对表单进行校验
- 需要对表单数据进行重置
- 需要在表单中添加额外的功能,比如动态添加表单项等
为了提高开发效率,我们可以对 el-form
组件进行封装,将这些重复性的需求抽象成通用的功能。这样,在后续的项目中,我们就可以直接使用封装好的组件,而无需重复开发。
预期效果
预期效果如下。
创建表单组件
先把架子搭起来,组件名为H3yunFormCompV1
,这个是随便取的哈。然后随便在哪个地方用上,方便测试。
<template><div><el-form></el-form></div>
</template><script>
export default {name: "H3yunFormCompV1",data() {return {}},props: {},mounted() {},methods: {}
}
</script><style scoped></style>
父组件传递表单数据,子组件遍历数据
把formData
数据传递过去。formData是一个列表,每个对象的结果如下{label: null, value: null}
非常的简单。
<H3yunFormCompV1 :formData="formData"></H3yunFormCompV1>data() {return {
formData: []
}
}
子组件如下:使用v-for
遍历formData,并把label和value取出来。
<template><div><el-form ref="form" :model="form" :inline="true"><el-form-item v-for="(item,key) in formData" :key="key" :label="item.label"><el-input v-model="item.value"></el-input></el-form-item></el-form></div>
</template><script>
export default {name: "H3yunFormCompV1",data() {return {form: {name: '',region: '',date1: '',date2: '',delivery: false,type: [],resource: '',desc: ''}}},props: {formData: Array},mounted() {},methods: {}
}
</script><style scoped></style>
添加disabled属性
子组件的完整代码
<template><div><el-row><el-formref="form":model="form"label-position="top"size="small"><el-col :span="6" v-for="(item,key) in formData" :key="key"><div class="box"><el-form-item :label="item.label"><el-input v-model="item.value" :disabled="item.disabled"></el-input></el-form-item></div></el-col></el-form></el-row></div>
</template><script>
export default {name: "H3yunFormCompV1",data() {return {form: {name: '',region: '',date1: '',date2: '',delivery: false,type: [],resource: '',desc: ''}}},props: {formData: Array},mounted() {},methods: {}
}
</script><style>
.box {font-size: 14px;padding: 6px 12px;color: #304265;background: #f8fafc;border-radius: 4px;min-height: 22px;box-sizing: content-box;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;
}.box .el-form-item__label {position: relative;font-size: 14px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #304265;font-weight: 400 !important;
}
</style>
效果如下:
适配JSON数据
先看效果,下面是销量预测的json数据。
代码如下:主要是把json数据解析为了一个个表单项。
<template><div><el-row><el-formref="form":model="form"label-position="top"size="small"><el-col :span="6" v-for="(item,key) in formStructure" :key="key"><div class="box"><el-form-item :label="item.label"><el-input v-model="item.value" :disabled="item.disabled"></el-input></el-form-item></div></el-col></el-form></el-row></div>
</template><script>
export default {name: "H3yunFormCompV1",data() {return {form: {},formStructure: []}},props: {formData: Array},watch: {// 监控父组件的表单数据formData: {handler(newFormData) {// 当 formData 变化时执行的操作// 解析新表单结构this.parseFormStructure(newFormData);},deep: true, // 深度监听,用于监听数组或对象内部的变化},},mounted() {// 解析新表单结构 - 第一次点击时执行this.parseFormStructure()},methods: {// 解析表单结构parseFormStructure() {// 清除表单结构和表单数据this.formStructure = []this.form = {}const formStructure = []// column的数据类型:{ label: null, value: null, prop: null, disabled: null, dataType: null}this.formData.forEach(column => {if (column.dataType == undefined) {column.dataType = 'text'}// 如果数据是json,需要把JSON数据装为column的结构if (column.dataType == 'json') {const label = column.labelconst prop = column.propconst jsonValue = column.valueconst disabled = column.disabledconst jsonObj = JSON.parse(jsonValue)// 构建column对象Object.keys(jsonObj).forEach(key => {const childLabel = `${label}.${key}`const childProp = `${prop}.${key}`const childValue = jsonObj[key]const childDisabled = disabledconst childColumn = {label: childLabel,value: childValue,prop: childProp,disabled: childDisabled,dataType: 'text'}formStructure.push(childColumn)})} else {formStructure.push(column)}})this.formStructure = formStructure}}
}
</script><style>
.box {font-size: 14px;padding: 6px 12px;color: #304265;background: #f8fafc;border-radius: 4px;min-height: 22px;box-sizing: content-box;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;
}.box .el-form-item__label {position: relative;font-size: 14px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #304265;font-weight: 400 !important;
}
</style>
表单提交
首先写个提交按钮,并添加个change表单提交事件。
<el-button type="primary" size="small" @change="submitForm">提交</el-button>
提交逻辑如下
// 提交的数据在this.form里面,表单验证通过后可以使用axios把表单数据提交到服务器。
submitForm() {// 使用 this.$refs.form.validate() 进行表单验证this.$refs.form.validate((valid) => {if (valid) {// 表单验证通过,执行提交操作// 在这里你可以使用 Axios 或其他方式提交数据到后端// 示例:假设有一个名为 submitData 的方法用于提交数据this.submitData();} else {// 表单验证失败,可以做一些处理,如提示用户this.$message.error('表单验证失败,请检查输入信息。');}});},submitData() {// 在这里执行提交数据的操作// 可以使用 Axios 或其他方式发送数据到后端// 示例:假设有一个名为 postData 的方法用于发送数据// postData(this.form)this.$message.success('表单提交成功!');}