我们在日常工作中经常遇到多数据的表单,写起来非常浪费时间+精力,市面上其他方法二次封装的el-form也是很棒的,这里我分享一下我自己写的封装方法
1.首先proform组件
<template>
<div class="wapper">
<ProForm
ref="form"
form-ref="freeForm"
:model="formData"
v-bind="formConfig"
:rules="rules"
/>
</div>
</template>
<script>
import { ProForm, DetailFormModal } from '@ajh/pro'
export default {
components: {
ProForm,
},
data() {
return {
// 表单数据console
formData: {
username: "",
number: 0,
time: "",
orgIdProduction: "",
sex: "",
love: [],
developmentMethods: "",
},
// el-form-item 配置项
formConfig: {
// labelWidth: 100, // 标题宽度
labelPosition: "left",
gutter: 12,
schemas: [
{
required: true,
label: "用户名",
field: "username",
component: "Input", // el-input可以省略,默认使用el-input
placeholder: "请输入用户名", // placeholder可以省略,默认显示“请输入+label”
span: 6, // 使用栅格布局
},
{
label: "数字输入",
field: "number",
component: "InputNumber",
controlsPosition: "right",
span: 6, // 使用栅格布局
},
{
label: "所属单位",
labelWidth: 180, // 标题宽度-优先级高
component: "Select",
field: "orgIdProduction",
span: 6,
componentProps: {
multiple: true, // 是否多选
clearable: true, // 能否清空
placeholder: "请选择",
options: [
{
label: "白庄煤矿",
value: "01076430",
},
{
label: "梁宝寺煤矿",
value: "01076323",
},
],
},
onChange: (value) => {
console.log(value);
},
},
{
label: "日期选择",
field: "time",
component: "DatePicker",
type: "datetime",
span: 6,
componentProps: {
width: "100%",
},
},
{
label: "性别",
field: "sex",
span: 6, // 支持栅格布局
component: "RadioGroup", // 可以传入任意组件
componentProps: {
options: [
{
label: "男",
value: 1,
},
{
label: "女",
value: 2,
},
],
},
onChange: (e) => {
console.log(e);
},
},
{
label: "菜单",
field: "developmentMethods",
span: 6,
component: "RadioGroup",
componentProps: {
options: [
{
label: "菜单1",
value: "menu1",
},
{
label: "菜单二",
value: "menu2",
},
],
onChange: (e) => {
console.log(e);
},
},
},
{
label: "兴趣爱好",
field: "love",
span: 6, // 支持栅格布局
component: "CheckboxGroup", // 可以传入任意组件
componentProps: {
options: [
{
label: "读书",
value: 1,
},
{
label: '菜单二',
value: 'menu2'
}
]
}
}
]
},
addFormConfig: {
labelWidth: 100, // 标题宽度
labelPosition: 'left',
gutter: 12,
schemas: [
{
label: '用户名',
field: 'username',
component: 'Input', // el-input可以省略,默认使用el-input
placeholder: '请输入用户名' // placeholder可以省略,默认显示“请输入+label”
},
{
label: '数字输入',
field: 'number',
component: 'InputNumber',
controlsPosition: 'right'
},
{
label: '所属单位',
labelWidth: 180, // 标题宽度-优先级高
component: 'Select',
field: 'orgIdProduction',
componentProps: {
multiple: true, // 是否多选
placeholder: '请选择',
options: [
{
label: '白庄煤矿',
value: '01076430'
},
{
label: '梁宝寺煤矿',
value: '01076323'
}
]
},
onChange: (value) => {
console.log(value)
}
},
{
label: '日期选择',
field: 'time',
component: 'DatePicker',
type: 'datetime',
componentProps: {
width: '100%'
}
},
{
label: '性别',
field: 'sex',
component: 'RadioGroup', // 可以传入任意组件
componentProps: {
options: [
{
label: '男',
value: 1
},
{
label: '女',
value: 2
}
]
},
onChange: (e) => {
console.log(e)
}
},
{
label: '兴趣爱好',
field: 'love',
component: 'CheckboxGroup', // 可以传入任意组件
componentProps: {
options: [
{
label: '读书',
value: 1
},
{
label: '写字',
value: 2
},
{
label: '听歌',
value: 4
}
]
},
onChange: (e) => {
console.log(e)
}
},
{
label: '菜单',
field: 'developmentMethods',
component: 'RadioGroup',
isButton: true,
clearable: true,
hidden: true,
componentProps: {
options: [
{
label: '菜单1',
value: 'menu1'
},
{
label: '菜单二',
value: 'menu2'
}
]
}
}
]
},
// el-form-item 验证规则
};
},
methods: {
// 级联类型
changeMajor(type) {
const json = {
primary: [
{
label: "数学",
value: 1,
},
{
label: "语文",
value: 2,
},
],
junior: [
{
label: "英语",
value: 5,
},
{
label: '生物',
value: 7
}
]
}
},
openAddFormModal() {
DetailFormModal.show({
title: '新增数据',
schemas: this.addFormConfig.schemas,
formData: this.formData
}).then(res => {
console.log('openAddFormModal', res)
})
}
}
}
</script>
<style>
.wapper {
background: #fff;
}
</style>
2.其他的二次封装组件包
<script lang="jsx">
import { Select, Option } from 'element-ui'
export default {
props: {
value: [String, Array],
options: {
type: Array,
default: () => []
},
multiple: {
type:Boolean
}
},
data() {
return {}
},
computed: {
model: {
get() {
return this.value
},
set(newVal) {
this.$emit('input', newVal)
}
}
},
render(h) {
const { model, options, multiple} = this
return (
<Select vModel={this.model} clearable multiple={multiple}>
{options.map((item) => {
return <Option label={item.label} value={item.value}></Option>
})}
</Select>
)
}
}
</script>
<script lang="jsx">
import { CheckboxGroup, Checkbox } from 'element-ui'
export default {
props: {
value: Array,
options: {
type: Array,
default: () => []
}
},
data() {
return {
}
},
computed: {
model: {
get() {
return this.value
},
set(newVal) {
this.$emit('input', newVal)
}
}
},
render(h) {
const { model, options } = this
return (
<CheckboxGroup vModel={this.model}>
{
options.map(item => {
return (
<Checkbox label={item.label} value={item.value}>
{item.label}
</Checkbox>
)
})
}
</CheckboxGroup>
)
}
}
</script>
<script lang="jsx">
import { Radio, RadioGroup} from 'element-ui'
export default {
props: {
value: [String, Array],
options: {
type: Array,
default: () => []
}
},
data() {
return {}
},
computed: {
model: {
get() {
return this.value
},
set(newVal) {
this.$emit('input', newVal)
}
}
},
render(h) {
const { model, options } = this
return (
<RadioGroup vModel={this.model}>
{options.map((item) => {
return <Radio label={item.label} value={item.value}></Radio>
})}
</RadioGroup>
)
}
}
</script>
3.然后引用子组件传入json配置项
<template>
<div class="wapper">
<ProForm
ref="form"
form-ref="freeForm"
:model="formData"
v-bind="formConfig"
:rules="rules"
/>
</div>
</template>
<script>
import { ProForm } from './ProForm'
export default {
components: {
ProForm,
},
data() {
return {
// 表单数据console
formData: {
username: "",
number: 0,
time: "",
orgIdProduction: "",
sex: "",
love: [],
developmentMethods: "",
},
// el-form-item 配置项
formConfig: {
// labelWidth: 100, // 标题宽度
labelPosition: "left",
gutter: 12,
schemas: [
{
required: true,
label: "用户名",
field: "username",
component: "Input", // el-input可以省略,默认使用el-input
placeholder: "请输入用户名", // placeholder可以省略,默认显示“请输入+label”
span: 6, // 使用栅格布局
},
{
label: "数字输入",
field: "number",
component: "InputNumber",
controlsPosition: "right",
span: 6, // 使用栅格布局
},
{
label: "所属单位",
labelWidth: 180, // 标题宽度-优先级高
component: "Select",
field: "orgIdProduction",
span: 6,
componentProps: {
multiple: true, // 是否多选
clearable: true, // 能否清空
placeholder: "请选择",
options: [
{
label: "白庄煤矿",
value: "01076430",
},
{
label: "梁宝寺煤矿",
value: "01076323",
},
],
},
onChange: (value) => {
console.log(value);
},
},
{
label: "日期选择",
field: "time",
component: "DatePicker",
type: "datetime",
span: 6,
componentProps: {
width: "100%",
},
},
{
label: "性别",
field: "sex",
span: 6, // 支持栅格布局
component: "RadioGroup", // 可以传入任意组件
componentProps: {
options: [
{
label: "男",
value: 1,
},
{
label: "女",
value: 2,
},
],
},
onChange: (e) => {
console.log(e);
},
},
{
label: "菜单",
field: "developmentMethods",
span: 6,
component: "RadioGroup",
componentProps: {
options: [
{
label: "菜单1",
value: "menu1",
},
{
label: "菜单二",
value: "menu2",
},
],
onChange: (e) => {
console.log(e);
},
},
},
{
label: "兴趣爱好",
field: "love",
span: 6, // 支持栅格布局
component: "CheckboxGroup", // 可以传入任意组件
componentProps: {
options: [
{
label: "读书",
value: 1,
},
{
label: '菜单二',
value: 'menu2'
}
]
}
}
]
},
addFormConfig: {
labelWidth: 100, // 标题宽度
labelPosition: 'left',
gutter: 12,
schemas: [
{
label: '用户名',
field: 'username',
component: 'Input', // el-input可以省略,默认使用el-input
placeholder: '请输入用户名' // placeholder可以省略,默认显示“请输入+label”
},
{
label: '数字输入',
field: 'number',
component: 'InputNumber',
controlsPosition: 'right'
},
{
label: '所属单位',
labelWidth: 180, // 标题宽度-优先级高
component: 'Select',
field: 'orgIdProduction',
componentProps: {
multiple: true, // 是否多选
placeholder: '请选择',
options: [
{
label: '白庄煤矿',
value: '01076430'
},
{
label: '梁宝寺煤矿',
value: '01076323'
}
]
},
onChange: (value) => {
console.log(value)
}
},
{
label: '日期选择',
field: 'time',
component: 'DatePicker',
type: 'datetime',
componentProps: {
width: '100%'
}
},
{
label: '性别',
field: 'sex',
component: 'RadioGroup', // 可以传入任意组件
componentProps: {
options: [
{
label: '男',
value: 1
},
{
label: '女',
value: 2
}
]
},
onChange: (e) => {
console.log(e)
}
},
{
label: '兴趣爱好',
field: 'love',
component: 'CheckboxGroup', // 可以传入任意组件
componentProps: {
options: [
{
label: '读书',
value: 1
},
{
label: '写字',
value: 2
},
{
label: '听歌',
value: 4
}
]
},
onChange: (e) => {
console.log(e)
}
},
{
label: '菜单',
field: 'developmentMethods',
component: 'RadioGroup',
isButton: true,
clearable: true,
hidden: true,
componentProps: {
options: [
{
label: '菜单1',
value: 'menu1'
},
{
label: '菜单二',
value: 'menu2'
}
]
}
}
]
},
// el-form-item 验证规则
};
},
methods: {
// 级联类型
changeMajor(type) {
const json = {
primary: [
{
label: "数学",
value: 1,
},
{
label: "语文",
value: 2,
},
],
junior: [
{
label: "英语",
value: 5,
},
{
label: '生物',
value: 7
}
]
}
},
openAddFormModal() {
DetailFormModal.show({
title: '新增数据',
schemas: this.addFormConfig.schemas,
formData: this.formData
}).then(res => {
console.log('openAddFormModal', res)
})
}
}
}
</script>
<style>
.wapper {
background: #fff;
}
</style>
最后展示效果:
大致就是这样,vue2+jsx+element-ui的el-form,封装了一层components,遍历的时候传入json的component区分是input输入框还是其他输入框,特殊输入框进行二次封装(el-select,el-radio)