Form 表单组件
基于 element-plus 二次封装的表单组件,支持配置化表单渲染、表单校验、动态表单项、远程/本地数据源、插槽自定义等能力。
具体的相关配置项,在下方都有说明,请先阅读完下方文档
组件导入
import { Form, useForm } from '@/components/Form'
快速开始
1.基本使用
<template>
<Form @register="formRegister" />
<el-button @click="onSubmit">提交</el-button>
</template>
<script setup lang="ts">
import { useForm, Form } from '@/components/Form'
const formColumns = [
{
prop: 'name',
label: '姓名',
component: 'Input',
required: true
},
{
prop: 'type',
label: '类型',
component: 'Select',
required: true,
componentProps: {
option: [
{ label: 'A', value: 'A' },
{ label: 'B', value: 'B' }
]
}
},
{
prop: 'date',
label: '日期',
component: 'DatePicker'
},
]
const { register: formRegister, methods: formMethods } = useForm({
formColumns,
formCols: 2,
})
async function onSubmit() {
await formMethods.validate()
// 只能获取到表单 formColumns配置项 中 含有prop 的 值
const data = await formMethods.getValue()
console.log('表单数据', data)
}
</script>
表单子组件
如何向表单子组件 componentProps 传递 属性 和 事件
该子组件将完全支持 element-plus 的 属性 与 事件
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'name',
label: '姓名',
component: 'Input',
// 传递到 componentProps 的属性和事件 将会完全的交给 el-input 组件,所以属性配置请阅读 el-input 的文档说明
componentProps:{
// 属性统一采用驼峰形式
maxlength: 200,
// 事件需要用 on 开头
onChange:(value){
...
}
}
}
]
Input 输入框
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'name',
label: '姓名',
component: 'Input',
}
]
InputPassword 密码框
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
label: '密码',
prop: 'password',
component: 'InputPassword',
}
]
InputTextArea 多行文本
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'description',
label: '说明',
component: 'InputTextArea',
}
]
InputNumber 数字输入
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'sort',
label: '排序',
component: 'InputNumber',
}
]
DatePicker 日期选择
基本使用
//.ts
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'dateRange',
label: '创建时间段',
component: 'DatePicker',
componentProps: {
type: 'daterange',
unlinkPanels: true,
valueFormat: 'YYYY-MM-DD'
}
}
]
// .vue
import { tableColumns } from './index';
import { useTable, Table } from '@/components/Table'
const { register: tableRegister, methods: tableMethods } = useTable({
api: getSupplierRoadBlacklistLogList,
tableColumns: tableColumns,
searchColumns: searchColumns,
isAutoHeight: true,
showPagination: true,
// 时间组件的 prop dateRange,需在这个地方格式化为 想要的字段
onBeforeLoad: (params) => {
let { dateRange = [], ...rest } = params
return { endDate: dateRange?.[1], startDate: dateRange?.[0], ...rest }
},
})
TimePicker 时间选择
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'createTime',
label: '创建时间段',
component: 'TimePicker',
}
]
RadioGroup 单选组
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'winningPriceVisible',
label: '竞价价格',
component: 'RadioGroup',
componentProps: {
option: [
{
label: '显示',
value: 1,
},
{
label: '隐藏',
value: 0,
},
],
},
}
]
Select 下拉选择
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'winningPriceVisible',
label: '竞价价格',
component: 'Select',
componentProps: {
option: [
{
label: '显示',
value: 1,
},
{
label: '隐藏',
value: 0,
},
],
},
}
]
字典使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'winningPriceVisible',
label: '竞价价格',
component: 'Select',
componentProps: {
// 传入 字典名称
dict: 'ORDER_STOP_STATUS'
},
}
]
ApiSelect 远程下拉
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'privinceId',
label: '考评省份',
component: 'ApiSelect',
componentProps: {
api: getProvinceList,
//value 的字段,该字段值将注入 该prop的值
valueField: 'privinceId',
// 显示的字段
labelField: 'privinceName',
params: {
pageSize: 10,
pageNum: 1
}
}
}
]
ApiSelectTree 远程树选择
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'categoryId',
label: '流程分类',
component: 'ApiSelectTree',
componentProps: {
//`filterable` 属性即可启用搜索功能
filterable: true,
// 传入 在 apis 文件中定义的 api 函数
api: listActTypes,
props: {
label: 'name',
children: 'children',
value: 'id'
}
}
}
]
ApiSearchSelect 远程搜索下拉
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'deptName',
label: '需求机构',
component: 'ApiSearchSelect',
componentProps: {
// 传入在 apis 文件中定义的 函数
api: listDeptPages,
labelField: 'name',
valueField: 'name',
// 根据个字段搜索
searchField: 'keyword',
pageSize: 50,
// 为true时,空值也可以搜索
// 默认为 false,即只有输入内容时,才允许搜索
defaultSearch: true
}
]
Text 纯广本
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'deptName',
label: '需求机构',
component: 'Text',
]
读取字典内容
基本使用
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'procurementMethodId',
label: '采购方式: ',
component: 'Text',
componentProps: {
dict: 'PURCHASE_DEPT_ID'
}
]
插槽使用
基本使用
//.ts
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'procurementMethodId',
label: '采购方式: ',
component: 'Text',
// 在 Form 组件中,可以不用带 form- 前缀
// 但在 Table 组件中,若是使用了 searchFormColumns,则需要带 form- 前缀
slot:'procurementMethodId',
//slot:'form-procurementMethodId'
]
//.vue
<Form @register="formRegister">
<template #procurementMethodId="{ model,prop }">
<!-- 通过 model[prop] 获取或修改 该字段的值
model 为表单对象, prop 为对应的 prop 字段 -->
<div>{{model[prop]}}</div>
</template>
</Form>
规则校验
必填校验
基本使用
//.ts
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'procurementMethodId',
label: '采购方式: ',
component: 'Text',
// 必填校验
required:true
]
自定义校验
注:该 rules 校验规则与 el-form 的rules 一致,请查看 el-form 相关文档
//.ts
import type { FormColumn } from '@/components/Form'
const formColumns:FormColumn = [
{
prop: 'procurementMethodId',
label: '采购方式: ',
component: 'Text',
// 对象形式
rules:{
required:true,
message:'采购方式为空'
},
// 数组形式(支持多个校验规则)
rules:[
{
required:true,
message:'采购方式为空',
trigger: 'blur'
},
{
...
}
]
]
表单布局
基本使用
//.vue
import { useForm, Form } from '@/components/Form'
const { register: formRegister, methods: formMethods } = useForm({
// grid 布局属性, 代表一行展示 几个组件,3: 一行3列。 5:一行5列
// 目前支持 1-7列。若想支持更多,请在 src/styles/safelist/grid.scss。文件内配置
"formCols": 3,
//每一列之前的间距,默认为 20,目前支持 1-100。 若想支持更多,请在 src/styles/safelist/grid.scss。文件内配置
gapX: 0,
labelPosition: 'right',
labelWidth: '130px',
formColumns,
})
表单禁用(禁用整个表单)
//.vue
import { useForm, Form } from '@/components/Form'
const { register: formRegister, methods: formMethods } = useForm({
"formCols": 3,
// 开启禁用
disabled:true,
gapX: 0,
labelPosition: 'right',
labelWidth: '130px',
formColumns,
})
1. 定义表单项配置
// formColumns.ts
import type { FormColumn } from '@/components/Form'
export const formColumns: FormColumn[] = [
{
prop: 'supplierName',
label: '供应商名称',
// 组件类型,查看types.ts 里的 ComponentType 类型。
component: 'Input',
required: true, // 表单校验
componentProps: {
placeholder: '请输入供应商名称',
},
},
{
prop: 'supplierType',
label: '供应商类型',
component: 'Select',
required: true,
componentProps: {
option: [
{ label: '企业', value: 'company' },
{ label: '个人', value: 'person' },
],
placeholder: '请选择类型',
},
},
{
prop: 'registerDate',
label: '注册日期',
component: 'DatePicker',
componentProps: {
type: 'date',
placeholder: '请选择注册日期',
},
},
]
2. 在页面中使用
<template>
<Form @register="formRegister" />
<el-button @click="onSubmit">提交</el-button>
</template>
<script setup lang="ts">
import { useForm, Form } from '@/components/Form'
import { formColumns } from './formColumns'
const { register: formRegister, methods: formMethods } = useForm({
formColumns,
formCols: 2, // 每行2列
gapX: 40, // 列间距
labelPosition: 'right',
labelWidth: '120px',
})
async function onSubmit() {
await formMethods.validate()
// 只能获取到表单 formColumns配置项 中 含有prop 的 值
const data = await formMethods.getValue()
console.log('表单数据', data)
}
</script>
API 说明
useForm(options)
options:表单配置对象,类型为FormProps- 返回值:
{ register, methods }register:注册方法,传递给<Form @register="..." />methods:表单操作方法,详见下表
methods 支持的方法
| 方法名 | 说明 | 参数 | |
|---|---|---|---|
| setProps | 设置表单属性 | props: FormProps | |
| validate | 校验整个表单 | 无 | |
| validateField | 校验部分字段 | props: string[] | |
| resetFields | 重置表单 | props?: string[] | |
| scrollToField | 滚动到指定字段 | prop: string | |
| clearValidate | 清除校验 | props?: string[] | |
| getValue | 获取表单数据 | 无 | |
| setValue | 设置表单数据 | props: any | |
| setPropValue | 设置单个字段 | prop: string, value: any | |
| updateFormColumn | 更新表单项 | props: Partial | Partial[] |
FormProps 配置项
| 属性名 | 说明 | 类型 |
|---|---|---|
| formColumns | 表单项配置 | FormColumn[] |
| formCols | 每行列数 | string | number |
| gapX | 列间距 | number |
| inline | 行内表单 | boolean |
| size | 尺寸 | 'large'|'default'|'small' |
| disabled | 禁用 | boolean |
| labelWidth | 标签宽度 | string | number |
| labelPosition | 标签位置 | 'left'|'right'|'top' |
| requireAsteriskPosition | 必填星号位置 | 'left'|'right' |
| hideRequiredAsterisk | 隐藏必填星号 | boolean |
| inlineMessage | 行内提示 | boolean |
| showMessage | 显示校验信息 | boolean |
| labelSuffix | 标签后缀 | string |
FormColumn 表单项配置
| 属性名 | 说明 | 类型 |
|---|---|---|
| prop | 字段名 | string |
| label | 标签 | string |
| component | 组件类型 | 见下方支持组件 |
| componentProps | 组件属性 | object/函数 |
| required | 是否必填 | boolean |
| defaultValue | 默认值 | any |
| ifShow | 是否显示 | boolean/函数 |
| rules | 校验规则 | array/object/函数 |
| span | 跨度(最多24) | string/number |
| tooltip | 标签提示 | string |
| divider | 分割线 | boolean |
| suffix | 标签后缀 | string |
| slot | 自定义插槽 | string |
支持的 component 类型
- Input(输入框)
- InputPassword(密码框)
- InputTextArea(多行文本)
- InputNumber(数字输入)
- DatePicker(日期选择)
- TimePicker(时间选择)
- RadioGroup(单选组)
- Select(下拉选择)
- ApiSelect(远程下拉)
- ApiSelectTree(远程树选择)
- Switch(开关)
- CheckboxGroup(多选组)
- IconPicker(图标选择)
- ImageUpload(图片上传)
- Tinymce(富文本)
- ApiSearchSelect(远程搜索下拉)
- Text(只读文本)
- InputOnlyNumber(仅数字输入)
进阶用法
- 支持通过
componentProps传递自定义属性、事件、远程/本地数据源等 - 支持通过
slot实现自定义表单项内容 - 支持动态控制表单项显示/隐藏、禁用、校验等
完整示例
<template>
<Form @register="formRegister" />
<el-button @click="onSubmit">提交</el-button>
</template>
<script setup lang="ts">
import { useForm, Form } from '@/components/Form'
const formColumns = [
{
prop: 'name',
label: '姓名',
component: 'Input',
required: true
},
{
prop: 'type',
label: '类型',
component: 'Select',
required: true,
componentProps: {
option: [
{ label: 'A', value: 'A' },
{ label: 'B', value: 'B' }
]
}
},
{
prop: 'date',
label: '日期',
component: 'DatePicker'
},
]
const { register: formRegister, methods: formMethods } = useForm({
formColumns,
formCols: 2,
})
async function onSubmit() {
await formMethods.validate()
// 只能获取到表单 formColumns配置项 中 含有prop 的 值
const data = await formMethods.getValue()
console.log('表单数据', data)
}
</script>
常见问题
- 表单项支持 element-plus 原生属性和事件
- 支持自定义插槽、动态表单、远程数据等
- 更多用法请参考实际业务代码和 element-plus 官方文档