Skip to content

Form 表单

对 ant-design-vue 的表单二次封装, 如果不满足或者觉得用不习惯, 完全可以用原始antdv表单来进行开发antdv 表单文档

默认配置

路径: apps/web-antd/src/adapter/form.ts

可根据需要进行默认配置更改 或者添加自己的自定义组件

添加自定义组件

路径: apps/web-antd/src/adapter/components/index.ts

ts
import { MyComponent } from "xxx";

export type FormComponentType = 在这里添加你的组件名称;

setupVbenForm<FormComponentType>({
  components: {
    // 添加组件
    MyComponent,
  },
  config: {
    // ant design vue组件库默认都是 v-model:value
    baseModelPropName: "value",
    modelPropNameMap: {
      // 如果你的组件绑定的不是v-model:value 需要在这里配置
      // 比如绑定的是 myValue 即v-model:myValue="xxx"
      MyComponent: "myValue",
    },
  },
});

useVbenForm

注意

有两个 useVbenForm 的导出

请导入import { useVbenForm } from '#/adapter/form'; 导入错误组件不会被加载

使用方式和 v2 版本的useForm类似, 定义组件布局更灵活(tailwind)

ts
// 注意不要导入错了
import { useVbenForm } from "#/adapter/form";

const [BasicForm, formApi] = useVbenForm({
  // 表单通用配置项 会影响该表单内所有组件
  commonConfig: {
    formItemClass: "col-span-2",
    componentProps: {
      // 建议配置此默认值 有些Select组件不会占满宽度
      class: "w-full",
    },
    // 表单项默认宽度
    labelWidth: 80,
  },
  schema: drawerSchema(),
  // 不显示默认的提交/重置按钮 在Modal/Drawer中使用
  showDefaultActions: false,
  // 默grid布局 两列
  wrapperClass: "grid-cols-2",
});

这里的schema用的getter写法, 主要由于在原始赋值写法中, 切换租户, 表单字典不会进行重加载, 这与 js 的加载机制有关, 确定不需要租户切换的表单, 可以直接使用赋值写法

ts
// 赋值写法
const schema = [];
// getter写法
const schema = () => [];

schema 配置项

ts
export const modalSchema: FormSchemaGetter = () => [
  /**
   * 这个一般是Modal/Drawer使用 需要隐藏
   */
  {
    component: "Input",
    dependencies: {
      // 使用css方式隐藏 但仍然可赋值
      show: () => false,
      // 注意这个一定要为['']  否则不能被正常隐藏
      triggerFields: [""],
    },
    // 参数名称
    fieldName: "configId",
    // 参数label
    label: "参数主键",
  },
  {
    component: "Input",
    fieldName: "configName",
    label: "参数名称",
    // 默认的校验规则 适用于Input等组件
    rules: "required",
  },
  {
    component: "RadioGroup",
    componentProps: {
      buttonStyle: "solid",
      // 使用字典的options
      options: getDictOptions(DictEnum.SYS_YES_NO),
      optionType: "button",
    },
    // 默认值
    defaultValue: "N",
    fieldName: "configType",
    label: "是否内置",
    // 默认的校验规则 适用于Select等组件
    rules: "selectRequired",
  },
  {
    component: "Input",
    fieldName: "configKey",
    label: "参数键名",
    rules: "required",
  },
  {
    component: "Input",
    fieldName: "configValue",
    label: "参数键值",
    rules: "required",
  },
  {
    component: "Textarea",
    // 参数名称
    fieldName: "remark",
    // 控制整个FormItem的class 使用tailwind类名
    formItemClass: "items-baseline",
    label: "备注",
  },
];

默认的校验规则

路径: apps/web-antd/src/adapter/form.ts

默认只会判断是否已经填写/选择, 需要复杂的校验需自定义实现

ts
defineRules: {
  // 输入项目必填国际化适配
  required: (value, _params, ctx) => {
    if (value === undefined || value === null || value.length === 0) {
      return $t('formRules.required', [ctx.label]);
    }
    return true;
  },
  // 选择项目必填国际化适配
  selectRequired: (value, _params, ctx) => {
    if (
      [false, null, undefined].includes(value) ||
    (isArray(value) && value.length === 0)) {
      return $t('formRules.selectRequired', [ctx.label]);
    }
    return true;
  },
},

如上面的schema 配置项代码, 然后在schema中使用:

ts
rules: 'required',
rules: 'selectRequired',

自定义校验规则

默认使用 zod 来进行表单校验

ts
import { z } from "#/adapter";
// 手机号可选, 但是填写的时候必须为指定格式
{
rules: z
  .string()
  .regex(/^1[3-9]\d{9}$/, '请输入正确的手机号码')
  .optional()
  .or(z.literal('')),
}

// 邮箱必填
{
rules: z
  .string()
  .email('请输入正确的手机号码')
}

// 自定义
rules: z
  .string()
  .min(1, { message: $t('authentication.passwordTip') })
  .refine((value) => value === xxxx, {
    message: $t('authentication.confirmPasswordTip'),
  });

如果更新表单组件参数

使用formApi.updateSchema:

例如需要在初始化时候, 更新selectoptions, 可以这样写:

ts
const [BasicForm, formApi] = useVbenForm({});

onMounted(async () => {
  const options = await api();
  // 更新options
  formApi.updateSchema([
    {
      filedName: "select",
      componentProps: {
        options,
      },
    },
  ]);
});

如何自定义表单布局

使用tailwindcss类名控制 具体使用grid布局 tailwind-grid

demo 预览: vben 自定义表单布局预览

代码: 使用 tailwind 自定义布局

Form 插槽使用(自定义组件)

TODO: 待补充

表单常用 api

ts
// 更新表单参数
formApi.updateSchema();
// 设置单个值
await formApi.setFieldValue(key, value);
// 设置多个值 注意默认只有在schema中定义的field才会被赋值
await formApi.setValues(values);
// 校验 valid为boolean 代表校验通过与否
const { valid } = await formApi.validate();
// 清空表单 包括校验信息
await formApi.resetForm();