Appearance
element-plus-fast-form 使用说明
本项目基于 Element Plus,采用"配置驱动+类封装+组合式 API"模式,适合中后台、低代码、动态表单等复杂场景。
目录
功能特性
1. 多组件类型支持
- Element Plus 组件:支持所有 Element Plus 表单组件(el-input、el-select、el-cascader 等)
- 自定义 Vue 组件:支持传入自定义组件,自动传递 formValue 和相关方法
- 插槽组件:使用 'slot' 类型实现完全自定义的表单项渲染
- 文本组件:支持纯文本或 HTML 字符串组件渲染
2. 后缀文字支持
- 表单项支持添加后缀文字,常用于显示单位或说明
- 自动调整布局,确保后缀文字正确显示
- 支持与表单项宽度的自适应配合
3. 异步配置支持
- 响应式配置:支持 reactive 和 ref 包装的配置对象
- 动态加载:支持异步获取表单配置并自动更新渲染
- 批量替换:提供 setFormConfigs 方法实现整个表单结构的动态切换
4. 嵌套表单(表单列表)
- 支持数组形式的嵌套表单结构
- 提供 addItem 和 removeItem 方法动态增删列表项
- 每个列表项可包含多个表单字段
- 支持在嵌套表单中使用插槽或自定义组件
5. 表单联动功能
- 方法联动:通过 hooks 方法实现表单项之间的联动
- 组件联动:在自定义组件中实现复杂的联动逻辑
- 插槽联动:通过插槽实现灵活的联动交互
6. 多表单实例管理
- 同一页面支持多个独立的表单实例
- 每个表单实例拥有独立的配置、数据和验证
7. 动态表单操作
- 组件属性动态修改:运行时修改表单项的 options、placeholder 等属性
- 表单项增删改:动态添加、删除、修改表单项配置
- 表单禁用控制:支持整个表单或单个表单项的禁用状态切换
8. 灵活的布局系统
- 基于 Element Plus 的 Row/Col 栅格系统
- 支持响应式布局配置
- 表单项自动适应容器宽度
- 支持自定义表单项和整体布局样式
9. 完整的表单验证
- 继承 Element Plus 的完整验证体系
- 支持同步和异步验证规则
- 提供表单实例引用,支持手动验证控制
10. TypeScript 支持
- 完整的类型定义覆盖
- 智能提示和类型检查
- 类型安全的 API 设计
预览
https://zhu-jiayu.github.io/element-plus-fast-form-demo/
安装与引入
此库依赖以下包,这些包需要在您的项目中安装:
bash
npm install vue@^3.2.13 element-plus@^2.7.4 @element-plus/icons-vue@^2.0.0
1. 安装 npm 包
bash
npm install element-plus-fast-form
# 或
yarn add element-plus-fast-form
2. 在项目中引入
ts
import { useForm } from "element-plus-fast-form";
// 或全局注册
import ElementPlusFastForm from "element-plus-fast-form";
app.use(ElementPlusFastForm);
API
hooks: useForm
定义:
ts
function useForm(config: IFormProps): IUseForm
方法名 | 入参类型 | 出参类型 | 说明 |
---|---|---|---|
useForm | IFormProps | Reactive<IFormProps> | Ref<IFormProps> | IUseForm | 获取表单实例和所有操作方法 |
注意点:入参类型如果是响应式数据,只作用于表单初始化时的异步渲染,如果需要修改表单属性,请使用setFormConfig 或 setComponentProps方法。
useForm 返回属性
属性名 | 类型 | 说明 |
---|---|---|
FastForm | DefineComponent | 表单组件,直接用于模板渲染 |
formValue | FormValueType | 响应式表单数据对象 |
rawFormValue | FormValueType | 原始表单数据对象(非响应式) |
formRef | Ref<FormInstance | undefined> | el-form 实例引用 |
useForm 返回方法
方法名 | 入参类型 | 返回类型 | 作用说明 |
---|---|---|---|
addItem | prop: string, config?: IFormconfig[] | void | 添加嵌套表单(config不传则添加相同的表单) |
removeItem | prop: string, key: number | void | 删除嵌套表单(如数组表单 remove) |
setComponentProps | prop: string, componentProps: Record<string, any> | void | 动态设置表单项组件属性 |
setFormValue | formData: Record<string, any> | void | 动态设置表单数据 |
setFormConfig | prop: string, config: Partial<IFormconfig> | void | 动态设置表单项配置 |
setFormConfigs | newFormConfig: IFormconfig[] | void | 批量替换整个表单配置 |
addFormConfig | config: IFormconfig, index?: number | void | 动态添加表单项 |
removeFormConfig | props: string[] | void | 动态删除表单项 |
setFormDisabled | disabled: boolean | void | 禁用/启用整个表单 |
removeItem(prop: string, key: number)
删除指定嵌套表单的第 key 项。setComponentProps(prop, componentProps)
动态修改某个表单项的组件属性(如 options、placeholder、disabled 等)。setFormValue(formData)
批量设置表单数据,常用于一键填充或重置。setFormConfig(prop, config)
动态修改某个表单项的配置(如校验规则、label、组件类型等)。setFormConfigs(newFormConfig)
批量替换整个表单配置,用于异步加载配置或动态切换表单结构。会清空原有配置和表单值,重新初始化。addFormConfig(config, index?)
动态添加表单项,可指定插入位置。removeFormConfig(props)
批量删除表单项,参数为 prop 数组。setFormDisabled(disabled)
禁用或启用整个表单。
类型定义
1. IOptions
ts
/**
* 表单组件通用选项类型,继承自 Element Plus 的 Select Option 类型。
* 用于 el-select、el-cascader、el-radio-group、el-checkbox-group 等组件的 options 配置。
*/
export interface IOptions {
/** 选项显示文本 */
label: string | number;
/** 选项实际值 */
value: string | number | boolean | object;
/** 是否禁用该选项 */
disabled?: boolean;
/** 可选:唯一标识(适合树形结构或自定义 key) */
key?: string | number;
/** 子选项(用于级联/树形结构) */
children?: IOptions[];
/** 其它自定义属性(兼容 Element Plus Option 类型) */
[key: string]: any;
}
2. IFormconfig
ts
/**
* 单个表单项的配置类型
*/
export interface IFormconfig {
/** 组件类型(如 el-input、el-select、slot、自定义组件等) */
component?: string | AsyncComponent | DefineComponent<any, any, any> | 'slot';
/** el-col 组件属性(如 span、offset 等) */
colProps?: Record<string, any>;
/** 组件本身的属性(参考element-plus 组件属性) */
componentProps?: Partial<{
options: IOptions[]; // 选项数组
placeholder: string; // 占位符
data: IOptions[]; // 其它数据
[key: string]: any; // 其它自定义属性
}>;
/** el-form-item 组件属性(参考element-plus el-form-item 属性) */
formItemProps: Partial<{
prop: string; // 字段名
label: string; // 标签
rules: Array<FormItemRule>; // 校验规则
model: FormValueType; // 表单默认值
[key: string]: any; // 其他属性,参考element-plus el-form-item 属性)
}>;
/** 嵌套子表单项(二维数组,用于嵌套表单) */
children?: Array<Array<IFormconfig>>;
/** 默认值,优先级高于formItemProps.model */
defaultValue?: any;
/** 后缀文字(如单位:%、元等) */
suffix?: string;
}
3. IFormProps
ts
/**
* 表单整体配置类型
*/
export interface IFormProps<T = IFormconfig> {
/** 表单项配置数组 */
formConfig: T[];
/** el-row 组件属性 */
rowProps?: Record<string, any>;
/** el-col 组件属性 */
colProps?: Record<string, any>;
/** el-form 组件属性 */
formProps?: Record<string, any>;
/** 是否显示嵌套表单操作按钮 */
showOperate?: boolean;
}
4. FormValueType
ts
/**
* 表单数据对象类型,key 为 prop,value 为表单项的值
*/
export type FormValueType = Record<string, any>;
5. INestedDataProps
ts
/**
* 嵌套表单项的数据结构(如数组表单的每一项)
*/
export interface INestedDataProps {
/** 父级 prop 名称 */
prop: string;
/** 当前项的唯一 key(如索引) */
key: number;
}
6. IUseForm
ts
/**
* useForm 返回的所有方法和属性类型
*/
export interface IUseForm {
/** 表单组件(直接用于模板渲染) */
FastForm: DefineComponent;
/** 响应式表单数据对象 */
formValue: FormValueType;
/** 原始表单数据对象(非响应式) */
rawFormValue: FormValueType;
/** el-form 实例引用 */
formRef: Ref<FormInstance | undefined>;
/** 添加嵌套表单项(如数组表单 push) */
addItem: (prop: string, config?: IFormconfig[]) => void;
/** 删除嵌套表单项(如数组表单 remove) */
removeItem: (prop: string, key: number) => void;
/** 动态设置表单项组件属性 */
setComponentProps: (prop: string, componentProps: Record<string, any>) => void;
/** 动态设置表单数据 */
setFormValue: (formData: Record<string, any>) => void;
/** 动态设置表单项配置 */
setFormConfig: (prop: string, config: Partial<IFormconfig>) => void;
/** 批量替换整个表单配置 */
setFormConfigs: (newFormConfig: IFormconfig[]) => void;
/** 动态添加表单项 */
addFormConfig: (config: IFormconfig, index?: number) => void;
/** 动态删除表单项 */
removeFormConfig: (props: string[]) => void;
/** 禁用/启用整个表单 */
setFormDisabled: (disabled: boolean) => void;
}
组件透传属性
根据配置中的 component
类型,表单会自动透传不同的属性和方法给对应的组件:
1. Slot 组件(component: 'slot')
当组件类型为 'slot'
时,会调用对应的插槽函数并透传以下属性:
ts
// 插槽函数接收的参数类型
interface SlotProps {
/** 整个表单的数据对象 */
formValue: FormValueType;
/** 当前字段的值 */
modelValue?: any;
/** 嵌套数据的键信息(仅在嵌套表单中存在) */
nestedKey?: INestedDataProps;
}
使用示例:
vue
<template>
<FastForm>
<template #fieldName="{ formValue, modelValue }">
<div>当前值: {{ modelValue }}</div>
<div>整个表单: {{ formValue }}</div>
</template>
</FastForm>
</template>
2. 自定义 Vue 组件
当组件类型为自定义 Vue 组件时,会透传以下属性和方法:
ts
// 自定义组件接收的 props 类型
interface CustomComponentProps {
/** 整个表单的数据对象 */
formValue: FormValueType;
/** 当前字段的属性名 */
prop?: string;
/** 当前字段的值 */
modelValue?: any;
/** 值更新回调函数 */
'onUpdate:modelValue'?: (value: any) => void;
/** 配置中的所有组件属性 */
[key: string]: any; // 来自 itemConfig.componentProps
// Form 类的所有公共方法:
/** 添加嵌套表单项 */
addItem: (prop: string, config?: IFormconfig[]) => void;
/** 删除嵌套表单项 */
removeItem: (prop: string, key: number) => void;
/** 动态设置表单项组件属性 */
setComponentProps: (prop: string, componentProps: Record<string, any>) => void;
/** 动态设置表单数据 */
setFormValue: (formData: Record<string, any>) => void;
/** 动态设置表单项配置 */
setFormConfig: (prop: string, config: Partial<IFormconfig>) => void;
/** 批量替换整个表单配置 */
setFormConfigs: (newFormConfig: IFormconfig[]) => void;
/** 动态添加表单项 */
addFormConfig: (config: IFormconfig, index?: number) => void;
/** 动态删除表单项 */
removeFormConfig: (props: string[]) => void;
/** 禁用/启用整个表单 */
setFormDisabled: (disabled: boolean) => void;
}
使用示例:
vue
<!-- 自定义头像上传组件 Avatar-upload/index.vue -->
<template>
<el-upload
class="avatar-uploader"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</template>
<script lang="ts" setup>
import { ref, defineProps, watch, defineEmits } from "vue";
import { ElMessage } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
const imageUrl = ref("");
// 接收透传的属性
const props = defineProps({
formValue: { // 整个表单数据对象
type: Object,
},
modelValue: { // 当前字段的值
type: String,
default: "",
},
prop: { // 当前字段的属性名
type: String,
},
// 还可以接收 Form 类的所有公共方法,如 addItem, removeItem, setComponentProps, setFormValue 等
});
// 监听 modelValue 变化,处理表单重置等场景
watch(
() => props.modelValue,
() => {
imageUrl.value = props.modelValue
}
);
// 定义事件,实现双向绑定
const emits = defineEmits(["update:modelValue"]);
const handleAvatarSuccess = (response, uploadFile) => {
imageUrl.value = URL.createObjectURL(uploadFile.raw!);
};
const beforeAvatarUpload = async (rawFile) => {
if (!["image/jpeg", "image/jpg", "image/png"].includes(rawFile.type)) {
ElMessage.error("请传图片");
return false;
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error("图片大小不能超过 2MB!");
return false;
}
// 处理文件并更新表单值
const filedata = await getImageInfo(rawFile);
imageUrl.value = filedata;
emits("update:modelValue", filedata); // 通知表单更新值
return true;
};
const getImageInfo = (file: any): Promise<string> => {
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
return new Promise((resolve) => {
fileReader.onload = function (e) {
resolve(this.result as string);
};
});
};
</script>
在表单配置中使用:
ts
import AvatarUpload from '@/components/Avatar-upload/index.vue';
const formConfig: IFormconfig[] = [
{
component: AvatarUpload, // 使用自定义组件
formItemProps: {
prop: 'avatar',
label: '头像上传'
},
// componentProps 中的属性也会透传给组件
componentProps: {
// 可以传递其他自定义属性
}
}
];
3. String 组件(HTML 标签字符串)
当组件类型为字符串(如 'div'
、'span'
等)时,会透传:
ts
// String 组件接收的属性
interface StringComponentProps {
/** 配置中的所有组件属性 */
[key: string]: any; // 来自 itemConfig.componentProps
}
// 子元素内容为 itemConfig.defaultValue 或 null
使用示例:
ts
const config: IFormconfig = {
component: 'div',
componentProps: {
class: 'custom-text',
style: { color: 'red' }
},
defaultValue: '这是一个文本内容',
formItemProps: {
prop: 'textField',
label: '文本标签'
}
};
4. Element Plus 组件(el- 前缀)
当组件类型为 Element Plus 组件(如 'el-input'
、'el-select'
等)时,会自动透传:
ts
// Element Plus 组件接收的属性
interface ElementComponentProps {
/** 当前字段的值 */
modelValue?: any;
/** 值更新回调函数 */
'onUpdate:modelValue': (value: any) => void;
/** 配置中的所有组件属性 */
[key: string]: any; // 来自 itemConfig.componentProps
/** 自动设置的样式 */
style: {
width: string; // 默认为 '100%' 或来自 componentProps.style.width
};
}
注意事项:
- 所有透传的属性都来自于
itemConfig.componentProps
配置 - 自定义组件会额外获得 Form 类的所有公共方法
- 透传的方法包括表单操作方法(如
addItem
、removeItem
)和动态配置方法(如setComponentProps
、setFormValue
等) - 嵌套表单中的组件会额外获得
nestedKey
参数 - 组件的双向绑定通过
modelValue
和onUpdate:modelValue
实现