Appearance
默认增加了 输入框(input)、选择器(select)、日期选择器(date)、数字输入框(inputNumber)、自定义组件(custom)组件。

vue
<template>
<DynamicForm
ref="dynamicFormRef"
:form-items="formItems"
:show-action-btn="true"
@submit="handleFormSubmit"
@reset="handleFormReset">
</DynamicForm>
<el-button type="primary" @click="submit">提交(可传递额外参数)</el-button>
</template>
<script setup lang="tsx">
import { ref } from "vue";
import type { DynamicFormExpose, FormItem } from "h-business-ui";
const dynamicFormRef = ref<DynamicFormExpose>();
const formItems = ref<FormItem[]>([
// 输入框
{
label: "用户名",
prop: "username",
type: "input",
required: true,
props: {
placeholder: "请输入用户名",
maxlength: 20,
showWordLimit: true,
},
},
{
label: "真实姓名",
prop: "realName",
type: "input",
required: true,
props: {
placeholder: "请输入真实姓名",
maxlength: 20,
showWordLimit: true,
},
},
// 自定义组件
{
label: "密码",
prop: "password",
type: "custom",
required: true,
props: {
placeholder: "请输入密码",
maxlength: 20,
showWordLimit: true,
},
render: (formData: Record<string, unknown>, prop: string, commonAttrs) => {
return <el-input v-model={formData[prop]} {...commonAttrs} />;
},
},
{
label: "性别",
prop: "gender",
type: "select",
options: [
{ label: "男", value: "male" },
{ label: "女", value: "female" },
],
},
{
label: "年龄",
prop: "age",
type: "inputNumber",
required: true,
// 只有当性别为男时才显示
hidden: (formData) => formData.gender !== "male",
},
{
label: "用户类型",
prop: "userType",
type: "select",
options: [
{ label: "普通用户", value: "normal" },
{ label: "VIP用户", value: "vip" },
],
required: true,
},
{
label: "手机号",
prop: "phone",
type: "input",
required: true,
props: {
placeholder: "请输入手机号",
maxlength: 11,
showWordLimit: true,
},
rules: [
{
pattern: /^1[3456789]\d{9}$/,
message: "请输入正确的手机号",
trigger: "blur",
},
],
// 当用户类型为VIP时,禁用手机号输入
disabled: (formData) => {
return formData.userType === "vip";
},
},
]);
// 表单提交
const handleFormSubmit = (
formData: Record<string, unknown>,
...args: unknown[]
) => {
console.log("表单提交数据:", formData);
console.log("额外参数:", ...args);
// 这里可以写提交逻辑
};
// 表单重置
const handleFormReset = () => {
console.log("表单已重置");
};
const submit = () => {
dynamicFormRef.value?.handleSubmit(close, "extra2");
};
</script>
<style lang="less" scoped></style>
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
formItems | FormItem[] | [] | 表单项配置,查看formItem说明 |
labelWidth | string | "120px" | 表单标签宽度 |
inline | boolean | false | 是否为行内表单 |
showActionBtn | boolean | true | 是否显示操作按钮 |
rules | FormRules | {} | 表单校验规则 |
formItem说明
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label | string | "" | 表单项标签 |
prop | string | "" | 表单项属性名 |
type | string | input | 表单项类型,可选值:input、select、date、inputNumber、custom |
props | object | {} | 表单项组件属性 |
labelWidth | string | "120px" | 表单项标签宽度 |
required | boolean | false | 是否必填 |
options | object[{label: string, value: string}][] | [] | 下拉选择器选项 |
placeholder | string | "" | 占位符 |
render | (formData: Record<string, unknown>, prop: string, commonAttrs: object,h:typeof createVNode) => VNode | undefined | 自定义渲染函数 |
events | object | undefined | 自定义事件,记得加on,如:{onBlur: (e: Event) => {console.log(e)}} |
hidden | function | undefined | 表单项是否隐藏 |
disabled | function | undefined | 表单项是否禁用 |
rules | FormRules | {} | 表单项校验规则,同element-plus中表单的校验规则。这里的值与表单上的rules合并。所以可以单独在表单项上去写,也可以在表单上写。也可以混合写。 |
###
| 事件名 | 参数 | 说明 |
|---|---|---|
submit | (formData: Record<string, unknown>, args: unknown[]) => void | 提交事件,参数为表单数据,args为额外的参数 |
reset | 无 | 重置事件 |
| 方法名 | 参数 | 返回值 | 描述 |
|---|---|---|---|
formRef | 无 | 无 | 表单组件实例 |
formData | 无 | Object | 表单数据 |
getFormData | 无 | Object | 获取表单数据(获取参数) |
handleSubmit | args: unknown[] | void | 提交表单 |
handleReset | 无 | void | 重置表单 |
setFormData | formData: Record<string, unknown> | void | 设置表单数据 |
validate | 无 | Boolean | 校验表单,同步 |
clearValidate | prop: string | string[] | void | 清除表单校验状态 |
typescript
import type { VNode, createVNode, Ref } from "vue";
import type { FormItemRule, FormInstance } from "element-plus";
export type FormItemType =
| "input"
| "select"
| "date"
| "daterange"
| "inputNumber"
| "custom";
export interface FormItem {
// 标签文本
label: string;
// 绑定字段
prop: string;
// 组件类型('input' | 'select' | 'date' | 'daterange' | 'inputNumber' | 'custom')
type: FormItemType;
// 组件属性
props?: Record<string, unknown>;
// 标签宽度
labelWidth?: string;
// 是否必填
required?: boolean;
// 下拉选项(仅当type为select时有效)
options?: {
label: string;
value: unknown;
}[];
// 占位符
placeholder?: string;
// 自定义渲染函数
render?: (
formData: Record<string, unknown>,
prop: string,
commonAttrs?: Record<string, unknown>,
h?: typeof createVNode,
) => VNode;
// 事件
events?: Record<string, (e: unknown) => void>;
// 可选,根据 formData 动态判断是否隐藏
hidden?: (formData: Record<string, unknown>) => boolean;
// 可选,根据 formData 动态判断是否禁用
disabled?: (formData: Record<string, unknown>) => boolean;
rules?: FormItemRule | FormItemRule[];
}
export interface Props {
formItems: FormItem[];
labelWidth?: string;
inline?: boolean;
showActionBtn?: boolean;
rules?: Record<string, FormItemRule | FormItemRule[]>;
}
export interface DynamicFormExpose {
formRef: Ref<FormInstance | undefined>;
formData: Ref<Record<string, unknown>>;
getFormData: () => Record<string, unknown>;
handleSubmit: (...args: unknown[]) => Promise<void>;
handleReset: () => void;
setFormData: (formData: Record<string, unknown>) => void;
validate: () => Promise<boolean>;
clearValidate: (props?: string | string[]) => void;
}