custom.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <script lang="ts" setup>
  2. import { h, markRaw } from 'vue';
  3. import { Page } from '@vben/common-ui';
  4. import { Card, Input, message } from 'antdv-next';
  5. import { useVbenForm, z } from '#/adapter/form';
  6. import TwoFields from './modules/two-fields.vue';
  7. const [Form] = useVbenForm({
  8. // 所有表单项共用,可单独在表单内覆盖
  9. commonConfig: {
  10. // 所有表单项
  11. componentProps: {
  12. class: 'w-full',
  13. },
  14. labelClass: 'w-2/6',
  15. },
  16. fieldMappingTime: [['field4', ['phoneType', 'phoneNumber'], null]],
  17. // 提交函数
  18. handleSubmit: onSubmit,
  19. // 垂直布局,label和input在不同行,值为vertical
  20. // 水平布局,label和input在同一行
  21. layout: 'horizontal',
  22. schema: [
  23. {
  24. // 组件需要在 #/adapter.ts内注册,并加上类型
  25. component: 'Input',
  26. fieldName: 'field',
  27. label: '自定义后缀',
  28. suffix: () => h('span', { class: 'text-red-600' }, '元'),
  29. },
  30. {
  31. component: 'Input',
  32. fieldName: 'field1',
  33. label: '自定义组件slot',
  34. renderComponentContent: () => ({
  35. prefix: () => 'prefix',
  36. suffix: () => 'suffix',
  37. }),
  38. },
  39. {
  40. component: h(Input, { placeholder: '请输入Field2' }),
  41. fieldName: 'field2',
  42. label: '自定义组件',
  43. modelPropName: 'value',
  44. rules: 'required',
  45. },
  46. {
  47. component: 'Input',
  48. fieldName: 'field3',
  49. label: '自定义组件(slot)',
  50. rules: 'required',
  51. },
  52. {
  53. component: markRaw(TwoFields),
  54. defaultValue: [undefined, ''],
  55. disabledOnChangeListener: false,
  56. fieldName: 'field4',
  57. formItemClass: 'col-span-1',
  58. label: '组合字段',
  59. rules: z
  60. .array(z.string().optional())
  61. .length(2, '请选择类型并输入手机号码')
  62. .refine((v) => !!v[0], {
  63. message: '请选择类型',
  64. })
  65. .refine((v) => !!v[1] && v[1] !== '', {
  66. message: '       输入手机号码',
  67. })
  68. .refine((v) => v[1]?.match(/^1[3-9]\d{9}$/), {
  69. // 使用全角空格占位,将错误提示文字挤到手机号码输入框的下面
  70. message: '       号码格式不正确',
  71. }),
  72. },
  73. ],
  74. // 中屏一行显示2个,小屏一行显示1个
  75. wrapperClass: 'grid-cols-1 md:grid-cols-2',
  76. });
  77. function onSubmit(values: Record<string, any>) {
  78. message.success({
  79. content: `form values: ${JSON.stringify(values)}`,
  80. });
  81. }
  82. </script>
  83. <template>
  84. <Page description="表单组件自定义示例" title="表单组件">
  85. <Card title="基础示例">
  86. <Form>
  87. <template #field3="slotProps">
  88. <Input placeholder="请输入" v-bind="slotProps" />
  89. </template>
  90. </Form>
  91. </Card>
  92. </Page>
  93. </template>