CustomerForm.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <template>
  2. <PageWrapper title="自定义组件示例">
  3. <CollapseContainer title="自定义表单">
  4. <BasicForm class="local_form" @register="register" @submit="handleSubmit">
  5. <template #f3="{ model, field, disabled }">
  6. <a-input v-model:value="model[field]" :disabled="disabled" placeholder="自定义slot" />
  7. </template>
  8. <template #colSlot_field5="{ model, field, disabled }">
  9. <FormItem :name="field" label="自定义colSlot" :rules="[{ required: true }]">
  10. <a-input
  11. v-model:value="model[field]"
  12. :disabled="disabled"
  13. placeholder="自定义colSlot"
  14. />
  15. </FormItem>
  16. </template>
  17. </BasicForm>
  18. </CollapseContainer>
  19. </PageWrapper>
  20. </template>
  21. <script lang="tsx" setup>
  22. import { h } from 'vue';
  23. import { BasicForm, FormSchema, useForm } from '@/components/Form';
  24. import { CollapseContainer } from '@/components/Container';
  25. import { useMessage } from '@/hooks/web/useMessage';
  26. import { Input, FormItem, FormItemRest, Select } from 'ant-design-vue';
  27. import { PageWrapper } from '@/components/Page';
  28. const custom_typeKey2typeValueRules = (model) => {
  29. return [
  30. {
  31. required: true,
  32. validator: async () => {
  33. if (!model.typeKey) return Promise.reject('请选择类型');
  34. if (!model.typeValue) return Promise.reject('请输入数据');
  35. Promise.resolve();
  36. },
  37. },
  38. ];
  39. };
  40. const schemas: FormSchema[] = [
  41. {
  42. field: 'field1',
  43. component: 'Input',
  44. label: 'render方式',
  45. colProps: {
  46. span: 8,
  47. },
  48. dynamicDisabled: ({ values }) => {
  49. return !!values.field_disabled;
  50. },
  51. rules: [{ required: true }],
  52. render: ({ model, field }, { disabled }) => {
  53. return h(Input, {
  54. placeholder: '请输入',
  55. value: model[field],
  56. onChange: (e) => {
  57. model[field] = e.target.value;
  58. },
  59. disabled,
  60. });
  61. },
  62. },
  63. {
  64. field: 'field2',
  65. component: 'Input',
  66. label: 'render组件slot',
  67. colProps: {
  68. span: 8,
  69. },
  70. dynamicDisabled: ({ values }) => {
  71. return !!values.field_disabled;
  72. },
  73. rules: [{ required: true }],
  74. renderComponentContent: (_, { disabled }) => {
  75. return {
  76. suffix: () => (disabled ? 'suffix_disabled' : 'suffix_default'),
  77. };
  78. },
  79. },
  80. {
  81. field: 'field3',
  82. component: 'Input',
  83. label: '自定义Slot',
  84. slot: 'f3',
  85. colProps: {
  86. span: 8,
  87. },
  88. dynamicDisabled: ({ values }) => {
  89. return !!values.field_disabled;
  90. },
  91. rules: [{ required: true }],
  92. },
  93. {
  94. field: 'field4',
  95. component: 'Input',
  96. // label: 'renderColContent渲染',
  97. /**!!!renderColContent 没有FormItem 包裹, 若想要 Form 提交需要带上数据须 <FormItem name={}></FormItem> 包裹: 示例如下*/
  98. renderColContent({ model, field }, { disabled }) {
  99. return (
  100. <FormItem name="field4" label="renderColContent渲染" rules={[{ required: true }]}>
  101. <Input placeholder="请输入" v-model:value={model[field]} disabled={disabled}></Input>
  102. </FormItem>
  103. );
  104. },
  105. colProps: {
  106. span: 8,
  107. },
  108. dynamicDisabled: ({ values }) => {
  109. return !!values.field_disabled;
  110. },
  111. },
  112. {
  113. field: 'field5',
  114. component: 'Input',
  115. label: '自定义colSlot',
  116. /**!!!renderColContent 没有FormItem 包裹, 若想要 Form 提交需要带上数据须 <FormItem name={}></FormItem> 包裹: 示例如下*/
  117. colSlot: 'colSlot_field5',
  118. colProps: {
  119. span: 8,
  120. },
  121. dynamicDisabled: ({ values }) => {
  122. return !!values.field_disabled;
  123. },
  124. },
  125. // 复合field 场景 自定义表单控件 一个控件包含多个表单录入 示例: 选择+输入
  126. {
  127. required: true,
  128. field: 'typeKey2',
  129. defaultValue: '测试类型',
  130. fields: ['typeValue2'],
  131. defaultValueObj: { typeValue2: '默认测试_文字' },
  132. component: 'Input',
  133. label: '复合field render',
  134. render({ model, field }, { disabled }) {
  135. return (
  136. <Input.Group compact>
  137. <Select
  138. disabled={disabled}
  139. style="width: 120px"
  140. allowClear
  141. v-model:value={model[field]}
  142. >
  143. <Select.Option value="测试类型">测试类型</Select.Option>
  144. <Select.Option value="测试名称">测试名称</Select.Option>
  145. </Select>
  146. <FormItem name="typeValue2" class="local_typeValue" rules={[{ required: true }]}>
  147. <FormItemRest>
  148. <Input
  149. placeholder="请输入"
  150. v-model:value={model['typeValue2']}
  151. disabled={disabled}
  152. />
  153. </FormItemRest>
  154. </FormItem>
  155. </Input.Group>
  156. );
  157. },
  158. colProps: {
  159. span: 8,
  160. },
  161. dynamicDisabled: ({ values }) => {
  162. return !!values.field_disabled;
  163. },
  164. },
  165. // 复合field 场景 自定义表单控件 一个控件包含多个表单录入 示例: 选择+输入
  166. {
  167. field: 'typeKey',
  168. defaultValue: '公司名称',
  169. fields: ['typeValue'],
  170. defaultValueObj: { typeValue: '默认文字' },
  171. component: 'Input',
  172. // label: 'renderColContent渲染',
  173. /**!!!renderColContent 没有FormItem 包裹, 若想要 Form 提交需要带上数据须 <FormItem name={}></FormItem> 包裹: 示例如下*/
  174. renderColContent({ model, field }, { disabled }) {
  175. return (
  176. <FormItem
  177. name="typeKey"
  178. label="复合field renderColContent"
  179. rules={custom_typeKey2typeValueRules(model)}
  180. >
  181. <Input.Group compact>
  182. <Select
  183. allowClear
  184. disabled={disabled}
  185. style="width: 120px"
  186. v-model:value={model[field]}
  187. >
  188. <Select.Option value="公司名称">公司名称</Select.Option>
  189. <Select.Option value="产品名称">产品名称</Select.Option>
  190. </Select>
  191. <FormItemRest>
  192. <Input
  193. style="width: calc(100% - 120px); margin-left: -1px;"
  194. placeholder="请输入"
  195. v-model:value={model['typeValue']}
  196. disabled={disabled}
  197. />
  198. </FormItemRest>
  199. </Input.Group>
  200. </FormItem>
  201. );
  202. },
  203. colProps: {
  204. span: 16,
  205. },
  206. dynamicDisabled: ({ values }) => {
  207. return !!values.field_disabled;
  208. },
  209. },
  210. {
  211. field: 'field_disabled',
  212. component: 'Switch',
  213. label: '是否禁用 编辑字段',
  214. colProps: {
  215. span: 8,
  216. },
  217. labelWidth: 200,
  218. },
  219. ];
  220. const { createMessage } = useMessage();
  221. const [register] = useForm({
  222. labelWidth: 120,
  223. schemas,
  224. actionColOptions: {
  225. span: 24,
  226. },
  227. });
  228. function handleSubmit(values: any) {
  229. console.log('submit values', values);
  230. createMessage.success('click search,values:' + JSON.stringify(values));
  231. }
  232. </script>
  233. <style lang="less" scoped>
  234. :deep(.local_form) .local_typeValue {
  235. width: calc(100% - 120px);
  236. margin-bottom: 0;
  237. margin-left: -1px;
  238. border-right: 0;
  239. .ant-input {
  240. border-radius: 0 6px 6px 0;
  241. }
  242. }
  243. </style>