在 Vue 3 项目中,我们常常需要快速构建动态表单。通过使用 Element Plus + 配置式 schema,
可以让表单渲染变得高度灵活和可复用,减少大量模板代码的重复。本文将带你实现一个通用的配置型表单组件。
1. 支持字段类型
- input:普通输入框
- textarea:多行文本框
- number:数字输入框
- select:下拉选择
- radio:单选组
- checkbox:多选组
- switch:开关
- date:日期选择器
2. SchemaForm 组件实现
<template>
<el-form
:model="modelValue"
:rules="rules"
ref="formRef"
label-width="120px"
>
<el-form-item
v-for="item in schema"
:key="item.prop"
:label="item.label"
:prop="item.prop"
>
<component
:is="getComponent(item)"
v-model="modelValue[item.prop]"
v-bind="item.componentProps"
>
<template v-if="item.type === 'select'" v-for="option in item.options" :key="option.value">
<el-option :label="option.label" :value="option.value" />
</template>
<template v-if="item.type === 'radio'" v-for="option in item.options" :key="option.value">
<el-radio :label="option.value">{{ option.label }}</el-radio>
</template>
<template v-if="item.type === 'checkbox'" v-for="option in item.options" :key="option.value">
<el-checkbox :label="option.value">{{ option.label }}</el-checkbox>
</template>
</component>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
modelValue: Object,
schema: Array,
rules: Object
})
const emits = defineEmits(['update:modelValue'])
const getComponent = (item) => {
switch (item.type) {
case 'input': return 'el-input'
case 'textarea': return 'el-input'
case 'number': return 'el-input-number'
case 'select': return 'el-select'
case 'radio': return 'el-radio-group'
case 'checkbox': return 'el-checkbox-group'
case 'switch': return 'el-switch'
case 'date': return 'el-date-picker'
default: return 'el-input'
}
}
</script>
3. 使用示例
const formData = ref({
username: '',
age: 18,
gender: '',
hobby: [],
isActive: false,
birth: ''
})
const schema = [
{ label: '用户名', prop: 'username', type: 'input' },
{ label: '年龄', prop: 'age', type: 'number' },
{
label: '性别', prop: 'gender', type: 'radio',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' }
]
},
{
label: '爱好', prop: 'hobby', type: 'checkbox',
options: [
{ label: '阅读', value: 'reading' },
{ label: '运动', value: 'sports' }
]
},
{ label: '是否启用', prop: 'isActive', type: 'switch' },
{
label: '出生日期', prop: 'birth', type: 'date',
componentProps: { type: 'date', placeholder: '选择日期' }
}
]
4. 表单校验
SchemaForm 支持通过 :rules
属性传入 Element Plus 的校验规则。推荐将其作为一个对象结构管理:
const rules = {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
birth: [{ required: true, message: '请选择出生日期', trigger: 'change' }]
}
5. 总结
通过 schema 配置 + 动态组件组合,我们可以快速搭建可扩展的表单生成器。在实际项目中,你还可以加入:
- 表单校验与重置
- 表单分组/嵌套
- 异步加载 options
- 自定义渲染插槽
如果你正在构建中后台系统,这种方式可以极大提高开发效率,也便于维护和复用。