Skip to content

PenForm 表单组件

支持的表单元素

  • Input 输入框
  • RadioGroup 单选框组
  • CheckboxGroup 多选框组
  • Select 下拉选择
  • InputNumber 数字输入框
  • Switch 开关
  • Divider 分割线

TIP

  1. 目前集成的只有上述常用的组件,因为集成太多不常用组件不利于体积的优化

  2. 除了以上的其他组件可以通过配置 typeCustom 结合插槽自定义实现,具体可参考下述代码示例

代码示例

vue
<template>
    <!-- 表单 -->
    <pen-form v-model="formData" :fields="fields" 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 fields = 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(fields);
const formData = ref(cloneDeep(initFormData));
</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';

export enum Form {
    Input = 'ElInput', // 输入框
    Select = 'Select', // 下拉选择
    RadioGroup = 'RadioGroup', // 单选框
    CheckboxGroup = 'CheckboxGroup', // 多选框
    Switch = 'ElSwitch', // 开关
    InputNumber = 'ElInputNumber', // 数字输入框
    Custom= 'Custom', // 自定义
    Divider= 'Divider' // 分割线
}

export type ExtraProps = {
    style?: string|CSSProperties;
    class?: string;
}

type BaseForm = {
    field: string; // 字段名
    formItemProps: Partial<FormItemProps> & ExtraProps; // el-form-item属性
    visible?: boolean|(() => boolean); // 是否显示
}

type CommonProps = {
    initValue?: any; // 初始值
    onChange?: (value: any) => void;
}

type OptionsProps = {
    options: any[] | (()=>any[]); // 下拉选项
    valueField: string; // 选项值字段
    labelField: string; // 选项标签字段
}

// 输入框属性类型
export type InputForm = BaseForm & CommonProps & {
    type: Form.Input;
    props?: Partial<InputProps&ExtraProps> & InputEventProps;
}

// 下拉选择属性类型
export type SelectForm = BaseForm & CommonProps & OptionsProps & {
    initValue: any;
    type: Form.Select;
    props?: Partial<ISelectProps&ExtraProps> & SelectEventProps;
}

type CheckProps = {
    border?: boolean;
    size?: 'large' | 'default' | 'small';
};

// 单选框属性类型
export type RadioGroupForm = BaseForm & CommonProps & OptionsProps & {
    type: Form.RadioGroup;
    props?: Partial<RadioGroupProps&ExtraProps> & RadioEventProps;
    radioProps?: ExtraProps & CheckProps;
}

// 多选框属性类型
export type CheckboxGroupForm = BaseForm & CommonProps & OptionsProps & {
    type: Form.CheckboxGroup;
    props?: Partial<CheckboxGroupProps&ExtraProps> & CheckboxEventProps;
    checkboxProps?: ExtraProps & CheckProps; // 多选框属性
}

// 开关属性类型
export type SwitchForm = BaseForm & CommonProps & {
    type: Form.Switch;
    props?: Partial<SwitchProps&ExtraProps> & SwitchEventProps;
}

// 数字输入框属性类型
export type InputNumberForm = BaseForm & CommonProps & {
    type: Form.InputNumber;
    props?: Partial<InputNumberProps&ExtraProps> & InputNumberEventProps;
}

// 自定义属性类型
type CustomForm= BaseForm & {
    type: Form.Custom;
    initValue: any; // 初始值
    props?: any;
}

// 分割线属性类型
type DividerForm = {
    type: Form.Divider;
    title: string; // 分割线标题
    props?: Partial<DividerProps&ExtraProps>;
    visible?: boolean|(() => boolean); // 是否显示
}

export type FormFieldItem = InputForm|SelectForm|RadioGroupForm|CheckboxGroupForm|SwitchForm|InputNumberForm|CustomForm|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