表单组件
概述
表单组件是一套基于 Element Plus 封装的表单解决方案,提供了丰富的表单控件和灵活的配置方式。通过 schema 配置即可快速构建复杂的表单界面,支持表单验证、联动、动态显示等功能。
基础用法
1. 引入组件
import { BasicForm, useForm } from '@/components/form'
2. 定义表单结构
const schema: FormItemSchema[] = [
{
prop: 'name',
label: '姓名',
component: 'Input',
colSpan: 12,
defaultValue: '',
rules: [{ required: true, message: '请输入姓名', trigger: 'blur' }]
},
{
prop: 'email',
label: '邮箱',
component: 'Input',
colSpan: 12,
componentProps: {
placeholder: '请输入邮箱地址'
}
}
]
const [BasicForm, formApi] = useForm({
labelPosition: 'right',
labelWidth: '100px',
schema: schema
})
3. 在模板中使用
<template>
<BasicForm @submit="handleSubmit" @reset="handleReset" />
</template>
核心概念
FormSchema 表单配置
属性 | 类型 | 说明 |
---|---|---|
labelPosition | 'left' | 'right' | 'top' | 标签位置 |
gutter | number | 栅格间隔 |
labelWidth | string | 标签宽度 |
schema | FormItemSchema[] | 表单项配置 |
showDefaultActions | boolean | 是否显示默认操作按钮 |
submitButtonText | string | 提交按钮文本 |
resetButtonText | string | 重置按钮文本 |
rules | Record<string, any> | 表单验证规则 |
inline | boolean | 是否行内表单 |
FormItemSchema 表单项配置
属性 | 类型 | 说明 |
---|---|---|
prop | string | 表单项属性名(必填) |
label | string | 表单项标签(必填) |
component | string | 表单项组件类型 |
defaultValue | any | 表单项默认值 |
componentProps | Record<string, any> | Function | 组件属性 |
colSpan | number | 栅格列数(1-24) |
rules | Array | 表单项验证规则 |
ifShow | boolean | Function | 动态显示控制(JS控制) |
show | boolean | Function | 动态显示控制(CSS控制) |
helpMessage | string | string[] | 帮助提示信息 |
ifDetail | boolean | Function | 详情表单显示控制 |
内置组件
基础组件
- Input - 文本输入框
{
prop: 'input',
label: '单行文本',
component: 'Input',
componentProps: {
type: 'text',
placeholder: '请输入内容'
}
}
- InputNumber - 数字输入框
{
prop: 'number',
label: '数字',
component: 'InputNumber'
}
- Select - 下拉选择框
{
prop: 'select',
label: '下拉选择',
component: 'Select',
componentProps: {
options: [
{ label: '选项1', value: '1' },
{ label: '选项2', value: '2' }
]
}
}
- RadioGroup - 单选框组
{
prop: 'radio',
label: '单选框',
component: 'RadioGroup',
componentProps: {
options: [
{ label: '选项1', value: '1' },
{ label: '选项2', value: '2' }
]
}
}
- CheckboxGroup - 多选框组
{
prop: 'checkbox',
label: '多选框',
component: 'CheckboxGroup',
componentProps: {
options: [
{ label: '选项1', value: '1' },
{ label: '选项2', value: '2' }
]
}
}
远程数据组件
- ApiSelect - 远程下拉选择
{
prop: 'apiSelect',
label: '远程下拉',
component: 'ApiSelect',
componentProps: {
api: '/api/data/select'
}
}
- ApiRadioGroup - 远程单选框
{
prop: 'apiRadio',
label: '远程单选',
component: 'ApiRadioGroup',
componentProps: {
api: '/api/data/select'
}
}
- ApiCheckboxGroup - 远程多选框
{
prop: 'apiCheckbox',
label: '远程多选',
component: 'ApiCheckboxGroup',
componentProps: {
api: '/api/data/select'
}
}
- ApiTreeSelect - 远程树形选择
{
prop: 'apiTree',
label: '远程树选择',
component: 'ApiTreeSelect',
componentProps: {
api: '/api/tree/data'
}
}
- ApiCascader - 远程级联选择
{
prop: 'apiCascader',
label: '远程级联',
component: 'ApiCascader',
componentProps: {
api: '/api/cascader/data'
}
}
字典组件
{
prop: 'dict',
label: '字典组件',
component: 'ApiDict',
componentProps: {
code: 'sex',
renderType: 'Select' // Select/RadioGroup/CheckboxGroup
}
}
日期组件
{
prop: 'date',
label: '日期选择',
component: 'DatePicker',
componentProps: {
type: 'date' // date/datetime/daterange/datetimerange等
}
}
其他组件
- Upload - 文件上传
{
prop: 'upload',
label: '文件上传',
component: 'Upload',
componentProps: {
listType: 'picture-card'
}
}
- Editor - 富文本编辑器
{
prop: 'content',
label: '内容',
component: 'Editor'
}
- IconPicker - 图标选择器
{
prop: 'icon',
label: '图标',
component: 'IconPicker'
}
高级功能
表单联动
通过 ifShow
和 show
属性实现表单联动:
{
prop: 'type',
label: '类型',
component: 'RadioGroup',
componentProps: {
options: [
{ label: '类型1', value: 1 },
{ label: '类型2', value: 2 }
]
}
},
{
prop: 'field1',
label: '字段1',
component: 'Input',
ifShow: (values) => values.type === 1 // 当type为1时显示
},
{
prop: 'field2',
label: '字段2',
component: 'Input',
show: (values) => values.type === 2 // 当type为2时显示(CSS控制显示隐藏)
}
动态属性
通过函数形式的 componentProps
实现动态属性:
{
prop: 'password',
label: '密码',
component: 'Input',
componentProps: (values) => {
return {
type: 'password',
disabled: values.status === 'disabled'
}
}
}
表单方法
通过 useForm
返回的 formApi
可以调用以下方法:
const [BasicForm, formApi] = useForm(schema)
// 表单验证
formApi.validate()
// 获取表单值
formApi.getValues()
// 设置表单值
formApi.setValues({ name: 'test' })
// 重置表单
formApi.resetFields()
// 更新表单项配置
formApi.updateSchema({
prop: 'name',
componentProps: { placeholder: '新占位符' }
})
完整示例
<template>
<div>
<el-radio-group v-model="labelPosition">
<el-radio-button value="left">左对齐</el-radio-button>
<el-radio-button value="right">右对齐</el-radio-button>
<el-radio-button value="top">顶部对齐</el-radio-button>
</el-radio-group>
<BasicForm
style="margin-top: 12px"
@submit="handleSubmit"
@reset="handleReset"
@change="handleChange"
/>
<!-- 显示表单数据 -->
<code>
<pre>{{ JSON.stringify(formData, null, 2) }}</pre>
</code>
</div>
</template>
<script setup lang="ts">
import { useForm } from '@/components/form'
const labelPosition = ref<'left' | 'right' | 'top'>('right')
const formData = ref({})
const schema = [
{
prop: 'name',
label: '姓名',
component: 'Input',
colSpan: 12,
rules: [{ required: true, message: '请输入姓名', trigger: 'blur' }]
},
{
prop: 'email',
label: '邮箱',
component: 'Input',
colSpan: 12
},
{
prop: 'status',
label: '状态',
component: 'RadioGroup',
componentProps: {
options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 }
]
}
},
{
prop: 'remark',
label: '备注',
component: 'Input',
colSpan: 24,
componentProps: { type: 'textarea', rows: 4 }
}
]
const [BasicForm, formApi] = useForm({
labelPosition: labelPosition.value,
labelWidth: '100px',
schema: schema
})
// 监听标签位置变化
watch(() => labelPosition.value, (val) => {
formApi.setState({ labelPosition: val })
})
// 表单提交
const handleSubmit = async (values: any) => {
console.log('表单提交:', values)
}
// 表单重置
const handleReset = () => {
console.log('表单重置')
}
// 表单值变化
const handleChange = (values: any) => {
formData.value = values
}
</script>
注意事项
- 所有表单项必须包含
prop
和label
属性 - 使用远程数据组件时,确保 API 返回的数据格式符合要求
- 表单联动时,
ifShow
会移除 DOM 元素,show
仅控制显示隐藏 - 通过
componentProps
可以传递任何组件支持的属性,具体看src/components/form/components/*
,和ElementPlus默认的属性,具体可以看Element-Plus文档