@iswangh/element-plus-kit-form
v0.3.0
Published
Element Plus Kit 表单组件包
Downloads
528
Readme
@iswangh/element-plus-kit-form
Element Plus Kit Form 组件,基于 Element Plus 的动态表单组件,支持通过配置快速生成表单。
📦 安装
npm install @iswangh/element-plus-kit-form注意:此包依赖 @iswangh/element-plus-kit-core,安装时会自动安装。
🚀 快速开始
基础用法
<script setup lang="ts">
import { ref } from 'vue'
import { WForm } from '@iswangh/element-plus-kit-form'
import type { FormItems } from '@iswangh/element-plus-kit-form'
const formItems: FormItems = [
{
prop: 'username',
label: '用户名',
compType: 'input',
},
{
prop: 'email',
label: '邮箱',
compType: 'input',
compProps: {
type: 'email',
},
},
]
const form = ref({
username: '',
email: '',
})
</script>
<template>
<WForm :model="form" :form-items="formItems" />
</template>引入样式
重要说明:WForm 组件已按需导入了所有内部使用的 Element Plus 组件样式,用户导入组件时样式会自动导入,无需额外配置。
自动导入(默认,推荐)
直接导入组件即可,样式会自动导入:
import { WForm } from '@iswangh/element-plus-kit-form'单独导入样式(可选)
如果需要在 CSS 文件中单独导入样式,可以使用:
import '@iswangh/element-plus-kit-form/style.css'注意:此样式文件已包含 WForm 内部使用的所有 Element Plus 组件样式(按需导入,约 185KB,gzip 约 24KB),无需再导入 Element Plus 的全局样式。
📖 API 文档
Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| model | 表单数据对象 | Record<string, any> | {} |
| formItems | 表单项配置数组 | FormItems | [] |
| rowProps | 行布局属性(ElRow 属性) | RowProps | {} |
| actionConfig | 操作按钮配置 | ActionConfig | {} |
继承 Element Plus Form 属性:组件继承所有 ElForm 的属性,如 rules、labelPosition、size 等。
Events
| 事件名 | 说明 | 参数 |
| --- | --- | --- |
| validate | 表单项验证事件 | (prop: FormItemProp, isValid: boolean, message: string) |
| change | 表单项值变化事件 | (extendedParams: FormItemEventExtendedParams, value: any) |
| action | 操作按钮点击事件 | (eventName: string) |
| search | 搜索按钮点击事件 | - |
| reset | 重置按钮点击事件 | - |
| submit | 提交按钮点击事件 | - |
| cancel | 取消按钮点击事件 | - |
| expand | 展开状态变化事件 | (value: boolean) |
可配置化事件:
- 除了在
WForm标签上监听事件,还可以在formItems配置对象的compProps中定义事件处理器 - 事件名以
on开头(如onBlur、onFocus、onInput等),直接接收原始事件参数(不需要extendedParams) - 可配置化事件优先级高于
WForm标签上的事件,如果同时定义了可配置化事件和标签事件,会优先使用可配置化事件 - 示例:
{ prop: 'username', compType: 'input', compProps: { onBlur: (event: FocusEvent) => { console.log('onBlur 事件:', event) }, }, }
Slots
| 插槽名 | 说明 | 作用域参数 |
| --- | --- | --- |
| {prop} | 自定义组件插槽,当 compType 为 custom 时使用 | FormItemSlotScope |
| form-item-{prop} | 表单项插槽,用于自定义表单项内容 | FormItemSlotScope |
| {prop}-{slotName} | 动态组件插槽,如 username-prefix、email-suffix | FormItemSlotScope |
| expand-toggle | 展开/折叠按钮插槽,用于自定义按钮 | { expanded: boolean, toggle: (value?: boolean) => void } |
可配置化插槽:
- 除了使用模板插槽,还可以在
formItems配置对象中直接定义插槽 - FormItem 插槽:在配置对象的
slots字段中定义,用于自定义el-form-item的插槽(如label、error等) - 动态组件插槽:在
compProps.slots字段中定义,用于自定义动态组件的插槽(如prefix、suffix等) - 可配置化插槽优先级高于模板插槽,如果同时定义了可配置化插槽和模板插槽,会优先使用可配置化插槽
- 插槽函数使用
h()函数创建 VNode,接收FormItemSlotScope参数 - 示例:
{ prop: 'username', compType: 'input', slots: { label: props => h('span', {}, props.formItem.label), }, compProps: { slots: { prefix: () => h(User), }, }, }
FormItem 配置
基础配置
interface FormItem<C extends FormItemComp = FormItemComp> {
prop: string // 表单字段名(必填)
label: string // 标签文本
compType: FormItemComp // 组件类型(必填)
compProps?: FormItemCompProps<C> // 组件属性配置 // 对于支持 options 的组件(如 select、cascader、radio、checkbox 等),支持两种配置方式:
// 1. 静态数组:compProps.options: [{ label: '选项1', value: '1' }]
// 2. 动态加载(compProps.optionsLoader):
// - 函数模式:optionsLoader: (formData: Record<string, unknown>) => [{ label: '选项1', value: '1' }]
// - 对象模式:optionsLoader: { loader: (formData: Record<string, unknown>) => [...], deps: ['field1'], immediate: true }
// 当同时配置 options 和 optionsLoader 时,optionsLoader 优先级更高
vIf?: boolean | ((data?: any) => boolean) // 条件渲染(v-if)
vShow?: boolean | ((data?: any) => boolean) // 显示/隐藏(v-show)
colProps?: ColProps // 列布局属性(ElCol 属性)
// ... 其他 ElFormItem 属性
}支持的组件类型
组件支持以下 Element Plus 表单组件:
autocomplete- 自动完成输入框cascader- 级联选择器checkbox- 复选框组color-picker- 颜色选择器color-picker-panel- 颜色选择器面板date-picker- 日期选择器date-picker-panel- 日期选择器面板input- 输入框input-number- 数字输入框input-tag- 标签输入框mention- 提及输入框radio- 单选框组rate- 评分select- 选择器select-v2- 虚拟列表选择器slider- 滑块switch- 开关time-picker- 时间选择器time-select- 时间选择transfer- 穿梭框tree-select- 树形选择器custom- 自定义组件(使用插槽)
使用示例
const formItems: FormItems = [
{
prop: 'username',
label: '用户名',
compType: 'input',
compProps: {
placeholder: '请输入用户名',
clearable: true,
},
rules: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
],
},
{
prop: 'age',
label: '年龄',
compType: 'input-number',
compProps: {
min: 0,
max: 120,
step: 1,
},
// 条件渲染:只有当 username 存在时才显示
vIf: (data) => !!data?.username,
},
{
prop: 'gender',
label: '性别',
compType: 'select',
compProps: {
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
],
},
},
]ActionConfig 配置
操作按钮配置用于自定义表单底部的操作按钮。
interface ActionConfig {
vIf?: boolean | ((data?: any) => boolean) // 是否显示操作区域
vShow?: boolean | ((data?: any) => boolean) // 显示/隐藏操作区域
buttons?: ActionConfigButtons[] // 按钮列表
expand?: ExpandRule // 默认展开规则(仅在 buttons 包含 'expand' 时生效)
}预设按钮
支持以下预设按钮:
'submit'- 提交按钮'reset'- 重置按钮'search'- 搜索按钮'cancel'- 取消按钮'expand'- 展开/折叠按钮(仅在inline模式下可用)
自定义按钮
interface ActionConfigButtonItem extends Partial<ButtonProps> {
label?: string // 按钮文字
eventName: string // 事件名称(必填)
}使用示例
const actionConfig: ActionConfig = {
buttons: [
'submit',
'reset',
{
label: '自定义按钮',
eventName: 'custom',
type: 'primary',
},
],
}💡 高级用法
条件渲染
使用 vIf 或 vShow 实现表单项的条件显示:
const formItems: FormItems = [
{
prop: 'username',
label: '用户名',
compType: 'input',
},
{
prop: 'email',
label: '邮箱',
compType: 'input',
// 只有当用户名存在时才显示邮箱字段
vIf: (data) => !!data?.username,
},
]自定义插槽
使用模板插槽自定义表单项内容:
<template>
<WForm :model="form" :form-items="formItems">
<template #username-prefix="{ formItem }">
<el-icon><User /></el-icon>
</template>
</WForm>
</template>可配置化插槽
除了使用模板插槽,还可以在 formItems 配置对象中直接定义插槽:
import { h } from 'vue'
import { User } from '@element-plus/icons-vue'
const formItems: FormItems = [
{
prop: 'username',
label: '用户名',
compType: 'input',
// FormItem 插槽配置
slots: {
label: props => h('span', { class: 'flex items-center gap-1' }, [
h('span', props.formItem.label),
h('span', { class: 'text-red-500' }, '*'),
]),
},
// 动态组件插槽配置
compProps: {
placeholder: '请输入用户名',
slots: {
prefix: () => h(User, { class: 'text-gray-400' }),
},
},
},
]优先级:可配置化插槽优先级高于模板插槽,如果同时定义了可配置化插槽和模板插槽,会优先使用可配置化插槽。
表单验证
const formItems: FormItems = [
{
prop: 'email',
label: '邮箱',
compType: 'input',
rules: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' },
],
},
]监听事件
在 WForm 标签上监听事件:
<template>
<WForm
:model="form"
:form-items="formItems"
@change="onChange"
@submit="onSubmit"
/>
</template>
<script setup lang="ts">
const onChange = (extendedParams: FormItemEventExtendedParams, value: any) => {
console.log('字段变化:', extendedParams.prop, value)
}
const onSubmit = () => {
console.log('提交表单:', form.value)
}
</script>可配置化事件
除了在 WForm 标签上监听事件,还可以在 formItems 配置对象中直接定义事件处理器:
const formItems: FormItems = [
{
prop: 'username',
label: '用户名',
compType: 'input',
compProps: {
placeholder: '请输入用户名',
// 动态组件的事件在 compProps 中定义
onBlur: (event: FocusEvent) => {
console.log('onBlur 事件:', event)
},
onFocus: (event: FocusEvent) => {
console.log('onFocus 事件:', event)
},
},
},
]优先级:可配置化事件优先级高于 WForm 标签上的事件,如果同时定义了可配置化事件和标签事件,会优先使用可配置化事件。
展开/折叠功能
表单支持展开/折叠功能,可以控制表单项的显示和隐藏,适用于字段较多的表单场景。
重要说明:
- 展开/折叠功能仅在
inline模式下可用(inline: true) - 通过
actionConfig.buttons包含'expand'来启用展开/折叠功能 - 通过
actionConfig.expand配置展开规则
基础用法
<template>
<WForm
:model="form"
:form-items="formItems"
inline
:action-config="{
buttons: ['expand', 'search', 'reset'],
expand: {
count: 3, // 默认展开前 3 个字段
},
}"
/>
</template>配置说明
展开规则通过 actionConfig.expand 配置,支持三种配置方式:
| 配置方式 | 说明 | 类型 | 示例 |
| --- | --- | --- | --- |
| count | 按字段数量展开(从第一个开始) | { count: number } | { count: 3 } |
| include | 指定展示的字段(白名单,字段 prop 数组) | { include: string[] } | { include: ['field1', 'field2'] } |
| exclude | 指定折叠的字段(黑名单,字段 prop 数组) | { exclude: string[] } | { exclude: ['field3', 'field4'] } |
配置优先级:exclude > include > count
展开规则高级配置
展开规则还支持以下高级配置:
| 配置项 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| autoExpandOnHover | 是否启用鼠标悬停自动展开功能 | boolean | false |
| scrollOnToggle | 是否在展开/收起后自动滚动到表单中心 | boolean | false |
| scrollIntoViewOptions | 自定义滚动选项(仅在 scrollOnToggle 为 true 时生效) | ScrollIntoViewOptions | { behavior: 'smooth', block: 'center', inline: 'nearest' } |
使用示例:
const actionConfig: ActionConfig = {
buttons: ['expand', 'search', 'reset'],
expand: {
count: 3, // 默认展开前 3 个字段
autoExpandOnHover: true, // 鼠标悬停时自动展开
scrollOnToggle: true, // 展开/收起后自动滚动
},
}受控模式
使用 v-model:expanded 实现受控模式:
<template>
<WForm
v-model:expanded="isExpanded"
:model="form"
:form-items="formItems"
inline
:action-config="{
buttons: ['expand', 'search', 'reset'],
expand: { count: 3 },
}"
/>
<el-button @click="formRef?.toggleExpand(true)">展开</el-button>
<el-button @click="formRef?.toggleExpand(false)">折叠</el-button>
</template>
<script setup lang="ts">
const isExpanded = ref(false)
const formRef = ref<InstanceType<typeof WForm>>()
// 或者使用组件暴露的方法
function toggle() {
formRef.value?.toggleExpand() // 切换
formRef.value?.toggleExpand(true) // 展开
formRef.value?.toggleExpand(false) // 折叠
}
// 或者直接使用 v-model:expanded
function toggleExpanded() {
isExpanded.value = !isExpanded.value
}
</script>自定义按钮
使用 expand-toggle 插槽自定义展开/折叠按钮:
<template>
<WForm
:model="form"
:form-items="formItems"
inline
:action-config="{
buttons: ['expand', 'search', 'reset'],
expand: { count: 3 },
}"
>
<template #expand-toggle="{ expanded, toggle }">
<el-button type="success" :icon="expanded ? ArrowUp : ArrowDown" @click="toggle()">
{{ expanded ? '收起高级搜索' : '展开高级搜索' }}
</el-button>
</template>
</WForm>
</template>