使用 Element Plus 构建通用配置型表单组件

在 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
  • 自定义渲染插槽

如果你正在构建中后台系统,这种方式可以极大提高开发效率,也便于维护和复用。

发表回复