PenForm 表单组件
支持的表单元素
- Input 输入框
- RadioGroup 单选框组
- CheckboxGroup 多选框组
- Select 下拉选择
- InputNumber 数字输入框
- Switch 开关
- Divider 分割线
TIP
目前集成的只有上述常用的组件,因为集成太多不常用组件不利于体积的优化
除了以上的其他组件可以通过配置
type为Custom结合插槽自定义实现,具体可参考下述代码示例
代码示例
vue
<template>
<!-- 表单 -->
<pen-form v-model="formData" :fields="formFields" label-width="100px">
<template #birthday>
<el-date-picker v-model="formData.birthday" type="date" placeholder="请选择日期"></el-date-picker>
</template>
</pen-form>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const formFields = defineForm([
{
type: Form.Divider,
title: '基本信息',
props: {
contentPosition: 'left'
}
},
{
type: Form.Input,
field: 'name',
formItemProps: {
label: '姓名',
},
props: {
placeholder: '请输入姓名',
clearable: true,
onChange: (e: any) => {
console.log(e)
},
onClear: () => {
console.log('clear')
}
}
},
{
type: Form.RadioGroup,
field: 'sex',
formItemProps: {
label: '性别',
},
options: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
labelField: 'label',
valueField: 'value',
radioProps: {
border: true,
}
},
{
type: Form.Divider,
title: '其他信息',
props: {
contentPosition: 'left'
}
},
{
type: Form.InputNumber,
field: 'age',
formItemProps: {
label: '年龄',
},
props: {
placeholder: '请输入年龄',
min: 1,
max: 120,
precision: 0,
controlsPosition: 'right',
style: {
width: '220px'
}
}
},
{
type: Form.Custom,
field: 'birthday',
formItemProps: {
label: '出生日期',
},
initValue: '',
}
])
const { fields, initFormData } = generateFormData(formFields);
const { currentRow, formData, action, actionName, init } = useForm(
initFormData,
(params) => {
// 初始化逻辑
}
)
</script>插槽
| 插槽名 | 说明 |
|---|---|
| [field] | [field]为具体字段名,如:name,实现自定义表单元素 |
属性类型
ts
import type { FormProps } from 'element-plus';
interface Props extends Partial<FormProps> {
fields: FormFieldItem[];
modelValue: Record<string, any>;
}FormFieldItem定义
ts
import type {
InputProps,
ISelectProps,
RadioGroupProps,
CheckboxGroupProps,
SwitchProps,
InputNumberProps,
DividerProps,
FormItemProps,
} from 'element-plus';
import type { CheckboxEventProps, ExtraProps, InputEventProps, InputNumberEventProps, RadioEventProps, SelectEventProps, SwitchEventProps } from '../../types';
import type { ComputedRef, Ref } from 'vue';
export enum Form {
Input = 'ElInput',
Select = 'Select',
RadioGroup = 'RadioGroup',
CheckboxGroup = 'CheckboxGroup',
Switch = 'ElSwitch',
InputNumber = 'ElInputNumber',
TimePicker = 'ElTimePicker',
DatePicker = 'ElDatePicker',
Cascader = 'ElCascader',
Custom = 'Custom',
Divider = 'Divider'
}
type BaseForm<T> = {
field: T;
formItemProps:
| (() => Partial<FormItemProps> & ExtraProps)
| ComputedRef<Partial<FormItemProps> & ExtraProps>
| Ref<Partial<FormItemProps> & ExtraProps>
| (Partial<FormItemProps> & ExtraProps);
visible?: boolean | (() => boolean) | Ref<boolean> | ComputedRef<boolean>;
}
type CommonProps = {
initValue?: any;
onChange?: (value: any) => void;
}
type OptionsProps = {
options: any[] | (() => any[]) | Ref<any[]> | ComputedRef<any[]>;
valueField: string;
labelField: string;
}
export type InputForm<T> = BaseForm<T> & CommonProps & {
type: Form.Input;
props?:
| (() => Partial<InputProps & ExtraProps> & InputEventProps)
| Ref<Partial<InputProps & ExtraProps> & InputEventProps>
| ComputedRef<Partial<InputProps & ExtraProps> & InputEventProps>
| (Partial<InputProps & ExtraProps> & InputEventProps);
}
export type SelectForm<T> = BaseForm<T> & CommonProps & OptionsProps & {
initValue: any;
type: Form.Select;
props?:
| (() => Partial<ISelectProps & ExtraProps> & SelectEventProps)
| Ref<Partial<ISelectProps & ExtraProps> & SelectEventProps>
| ComputedRef<Partial<ISelectProps & ExtraProps> & SelectEventProps>
| (Partial<ISelectProps & ExtraProps> & SelectEventProps);
}
type CheckProps = {
border?: boolean;
size?: 'large' | 'default' | 'small';
};
export type RadioGroupForm<T> = BaseForm<T> & CommonProps & OptionsProps & {
type: Form.RadioGroup;
props?:
| (() => Partial<RadioGroupProps & ExtraProps> & RadioEventProps)
| Ref<Partial<RadioGroupProps & ExtraProps> & RadioEventProps>
| ComputedRef<Partial<RadioGroupProps & ExtraProps> & RadioEventProps>
| (Partial<RadioGroupProps & ExtraProps> & RadioEventProps);
radioProps?:
| (() => ExtraProps & CheckProps)
| Ref<ExtraProps & CheckProps>
| ComputedRef<ExtraProps & CheckProps>
| (ExtraProps & CheckProps);
}
export type CheckboxGroupForm<T> = BaseForm<T> & CommonProps & OptionsProps & {
type: Form.CheckboxGroup;
props?:
| (() => Partial<CheckboxGroupProps & ExtraProps> & CheckboxEventProps)
| Ref<Partial<CheckboxGroupProps & ExtraProps> & CheckboxEventProps>
| ComputedRef<Partial<CheckboxGroupProps & ExtraProps> & CheckboxEventProps>
| (Partial<CheckboxGroupProps & ExtraProps> & CheckboxEventProps);
checkboxProps?:
| (() => ExtraProps & CheckProps)
| Ref<ExtraProps & CheckProps>
| ComputedRef<ExtraProps & CheckProps>
| (ExtraProps & CheckProps);
}
export type SwitchForm<T> = BaseForm<T> & CommonProps & {
type: Form.Switch;
props?:
| (() => Partial<SwitchProps & ExtraProps> & SwitchEventProps)
| Ref<Partial<SwitchProps & ExtraProps> & SwitchEventProps>
| ComputedRef<Partial<SwitchProps & ExtraProps> & SwitchEventProps>
| (Partial<SwitchProps & ExtraProps> & SwitchEventProps);
}
export type InputNumberForm<T> = BaseForm<T> & CommonProps & {
type: Form.InputNumber;
props?:
| (() => Partial<InputNumberProps & ExtraProps> & InputNumberEventProps)
| Ref<Partial<InputNumberProps & ExtraProps> & InputNumberEventProps>
| ComputedRef<Partial<InputNumberProps & ExtraProps> & InputNumberEventProps>
| (Partial<InputNumberProps & ExtraProps> & InputNumberEventProps);
}
type CustomForm<T> = BaseForm<T> & {
type: Form.Custom;
initValue: any;
props?: any;
}
export type DividerForm = {
type: Form.Divider;
title: string;
props?:
| (() => Partial<DividerProps & ExtraProps>)
| Ref<Partial<DividerProps & ExtraProps>>
| ComputedRef<Partial<DividerProps & ExtraProps>>
| Partial<DividerProps & ExtraProps>;
visible?: boolean | (() => boolean) | Ref<boolean> | ComputedRef<boolean>;
}
export type FormFieldItem<T> = InputForm<T> | SelectForm<T> | RadioGroupForm<T> | CheckboxGroupForm<T> | SwitchForm<T> | InputNumberForm<T> | CustomForm<T> | DividerForm;事件类型
ts
export type InputEventProps = {
onBlur?: (event: FocusEvent) => void; // 失焦事件
onFocus?: (event: FocusEvent) => void; // 聚焦事件
onChange?: (value: string | number) => void; // 值改变事件
onInput?: (value: string | number) => void; // 输入事件
onClear?: () => void; // 清空事件
}
export type SelectEventProps = {
onChange?: (value: any) => void; // 值改变事件
onVisibleChange?: (visible: boolean) => void; // 下拉框显示隐藏事件
onRemoveTag?: (tagValue: any) => void; // 移除标签事件
onClear?: () => void; // 清空事件
onBlur?: (event: FocusEvent) => void; // 失焦事件
onFocus?: (event: FocusEvent) => void; // 聚焦事件
}
export type CheckboxEventProps = {
onChange?: (value: string[] | number[]) => void; // 值改变事件
}
export type RadioEventProps = {
onChange?: (value: string | number | boolean) => void; // 值改变事件
}
export type SwitchEventProps = {
onChange?: (val: boolean | string | number) => void; // 值改变事件
}
export type InputNumberEventProps = {
onChange?: (currentValue: number | undefined, oldValue: number | undefined) => void; // 值改变事件
onBlur?: (event: FocusEvent) => void; // 失焦事件
onFocus?: (event: FocusEvent) => void; // 聚焦事件
}Expose属性
| 属性名 | 说明 | 类型 |
|---|---|---|
| instance | 表格实例 | Ref<FormInstance> |
| validate | 对整个表单的内容进行验证。 接收一个回调函数,或返回 Promise。 | (callback?: FormValidateCallback) => Promise<void> |
| resetFields | 重置该表单项,将其值重置为初始值,并移除校验结果。 | (props?: Arrayable<FormItemProp> | undefined) => void |
| clearValidate | 清理某个字段的表单验证信息。 | (props?: Arrayable<FormItemProp> | undefined) => void |