Commit 47a448b8aea572e54dac97dc4f9fb6c1c005685a
1 parent
5138e447
feat(form): add `Divider` for schema component type
新增Divider用于较长表单的区域分割
Showing
8 changed files
with
94 additions
and
41 deletions
CHANGELOG.zh_CN.md
src/components/Form/src/BasicForm.vue
@@ -29,7 +29,7 @@ | @@ -29,7 +29,7 @@ | ||
29 | #[item]="data" | 29 | #[item]="data" |
30 | v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']" | 30 | v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']" |
31 | > | 31 | > |
32 | - <slot :name="item" v-bind="data"></slot> | 32 | + <slot :name="item" v-bind="data || {}"></slot> |
33 | </template> | 33 | </template> |
34 | </FormAction> | 34 | </FormAction> |
35 | <slot name="formFooter"></slot> | 35 | <slot name="formFooter"></slot> |
@@ -132,7 +132,11 @@ | @@ -132,7 +132,11 @@ | ||
132 | } | 132 | } |
133 | } | 133 | } |
134 | } | 134 | } |
135 | - return schemas as FormSchema[]; | 135 | + if (unref(getProps).showAdvancedButton) { |
136 | + return schemas.filter((schema) => schema.component !== 'Divider') as FormSchema[]; | ||
137 | + } else { | ||
138 | + return schemas as FormSchema[]; | ||
139 | + } | ||
136 | }); | 140 | }); |
137 | 141 | ||
138 | const { handleToggleAdvanced } = useAdvanced({ | 142 | const { handleToggleAdvanced } = useAdvanced({ |
src/components/Form/src/componentMap.ts
@@ -18,6 +18,7 @@ import { | @@ -18,6 +18,7 @@ import { | ||
18 | TreeSelect, | 18 | TreeSelect, |
19 | Slider, | 19 | Slider, |
20 | Rate, | 20 | Rate, |
21 | + Divider, | ||
21 | } from 'ant-design-vue'; | 22 | } from 'ant-design-vue'; |
22 | 23 | ||
23 | import RadioButtonGroup from './components/RadioButtonGroup.vue'; | 24 | import RadioButtonGroup from './components/RadioButtonGroup.vue'; |
@@ -61,6 +62,7 @@ componentMap.set('IconPicker', IconPicker); | @@ -61,6 +62,7 @@ componentMap.set('IconPicker', IconPicker); | ||
61 | componentMap.set('InputCountDown', CountdownInput); | 62 | componentMap.set('InputCountDown', CountdownInput); |
62 | 63 | ||
63 | componentMap.set('Upload', BasicUpload); | 64 | componentMap.set('Upload', BasicUpload); |
65 | +componentMap.set('Divider', Divider); | ||
64 | 66 | ||
65 | export function add(compName: ComponentType, component: Component) { | 67 | export function add(compName: ComponentType, component: Component) { |
66 | componentMap.set(compName, component); | 68 | componentMap.set(compName, component); |
src/components/Form/src/components/FormItem.vue
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; | 5 | import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; |
6 | import type { TableActionType } from '/@/components/Table'; | 6 | import type { TableActionType } from '/@/components/Table'; |
7 | import { defineComponent, computed, unref, toRefs } from 'vue'; | 7 | import { defineComponent, computed, unref, toRefs } from 'vue'; |
8 | - import { Form, Col } from 'ant-design-vue'; | 8 | + import { Form, Col, Divider } from 'ant-design-vue'; |
9 | import { componentMap } from '../componentMap'; | 9 | import { componentMap } from '../componentMap'; |
10 | import { BasicHelp } from '/@/components/Basic'; | 10 | import { BasicHelp } from '/@/components/Basic'; |
11 | import { isBoolean, isFunction, isNull } from '/@/utils/is'; | 11 | import { isBoolean, isFunction, isNull } from '/@/utils/is'; |
@@ -73,11 +73,17 @@ | @@ -73,11 +73,17 @@ | ||
73 | 73 | ||
74 | const getComponentsProps = computed(() => { | 74 | const getComponentsProps = computed(() => { |
75 | const { schema, tableAction, formModel, formActionType } = props; | 75 | const { schema, tableAction, formModel, formActionType } = props; |
76 | - const { componentProps = {} } = schema; | ||
77 | - if (!isFunction(componentProps)) { | ||
78 | - return componentProps; | 76 | + let { componentProps = {} } = schema; |
77 | + if (isFunction(componentProps)) { | ||
78 | + componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {}; | ||
79 | } | 79 | } |
80 | - return componentProps({ schema, tableAction, formModel, formActionType }) ?? {}; | 80 | + if (schema.component === 'Divider') { |
81 | + componentProps = Object.assign({ type: 'horizontal' }, componentProps, { | ||
82 | + orientation: 'left', | ||
83 | + plain: true, | ||
84 | + }); | ||
85 | + } | ||
86 | + return componentProps; | ||
81 | }); | 87 | }); |
82 | 88 | ||
83 | const getDisable = computed(() => { | 89 | const getDisable = computed(() => { |
@@ -300,38 +306,46 @@ | @@ -300,38 +306,46 @@ | ||
300 | } | 306 | } |
301 | 307 | ||
302 | function renderItem() { | 308 | function renderItem() { |
303 | - const { itemProps, slot, render, field, suffix } = props.schema; | 309 | + const { itemProps, slot, render, field, suffix, component, label } = props.schema; |
304 | const { labelCol, wrapperCol } = unref(itemLabelWidthProp); | 310 | const { labelCol, wrapperCol } = unref(itemLabelWidthProp); |
305 | const { colon } = props.formProps; | 311 | const { colon } = props.formProps; |
306 | 312 | ||
307 | - const getContent = () => { | ||
308 | - return slot | ||
309 | - ? getSlot(slots, slot, unref(getValues)) | ||
310 | - : render | ||
311 | - ? render(unref(getValues)) | ||
312 | - : renderComponent(); | ||
313 | - }; | ||
314 | - | ||
315 | - const showSuffix = !!suffix; | ||
316 | - const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix; | ||
317 | - | ||
318 | - return ( | ||
319 | - <Form.Item | ||
320 | - name={field} | ||
321 | - colon={colon} | ||
322 | - class={{ 'suffix-item': showSuffix }} | ||
323 | - {...(itemProps as Recordable)} | ||
324 | - label={renderLabelHelpMessage()} | ||
325 | - rules={handleRules()} | ||
326 | - labelCol={labelCol} | ||
327 | - wrapperCol={wrapperCol} | ||
328 | - > | ||
329 | - <div style="display:flex"> | ||
330 | - <div style="flex:1">{getContent()}</div> | ||
331 | - {showSuffix && <span class="suffix">{getSuffix}</span>} | ||
332 | - </div> | ||
333 | - </Form.Item> | ||
334 | - ); | 313 | + if (component === 'Divider') { |
314 | + return ( | ||
315 | + <Col span={24}> | ||
316 | + <Divider {...unref(getComponentsProps)}>{label}</Divider> | ||
317 | + </Col> | ||
318 | + ); | ||
319 | + } else { | ||
320 | + const getContent = () => { | ||
321 | + return slot | ||
322 | + ? getSlot(slots, slot, unref(getValues)) | ||
323 | + : render | ||
324 | + ? render(unref(getValues)) | ||
325 | + : renderComponent(); | ||
326 | + }; | ||
327 | + | ||
328 | + const showSuffix = !!suffix; | ||
329 | + const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix; | ||
330 | + | ||
331 | + return ( | ||
332 | + <Form.Item | ||
333 | + name={field} | ||
334 | + colon={colon} | ||
335 | + class={{ 'suffix-item': showSuffix }} | ||
336 | + {...(itemProps as Recordable)} | ||
337 | + label={renderLabelHelpMessage()} | ||
338 | + rules={handleRules()} | ||
339 | + labelCol={labelCol} | ||
340 | + wrapperCol={wrapperCol} | ||
341 | + > | ||
342 | + <div style="display:flex"> | ||
343 | + <div style="flex:1">{getContent()}</div> | ||
344 | + {showSuffix && <span class="suffix">{getSuffix}</span>} | ||
345 | + </div> | ||
346 | + </Form.Item> | ||
347 | + ); | ||
348 | + } | ||
335 | } | 349 | } |
336 | 350 | ||
337 | return () => { | 351 | return () => { |
src/components/Form/src/hooks/useFormEvents.ts
@@ -149,7 +149,9 @@ export function useFormEvents({ | @@ -149,7 +149,9 @@ export function useFormEvents({ | ||
149 | updateData = [...data]; | 149 | updateData = [...data]; |
150 | } | 150 | } |
151 | 151 | ||
152 | - const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field); | 152 | + const hasField = updateData.every( |
153 | + (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field) | ||
154 | + ); | ||
153 | 155 | ||
154 | if (!hasField) { | 156 | if (!hasField) { |
155 | error( | 157 | error( |
@@ -169,7 +171,9 @@ export function useFormEvents({ | @@ -169,7 +171,9 @@ export function useFormEvents({ | ||
169 | updateData = [...data]; | 171 | updateData = [...data]; |
170 | } | 172 | } |
171 | 173 | ||
172 | - const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field); | 174 | + const hasField = updateData.every( |
175 | + (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field) | ||
176 | + ); | ||
173 | 177 | ||
174 | if (!hasField) { | 178 | if (!hasField) { |
175 | error( | 179 | error( |
src/components/Form/src/types/index.ts
src/views/demo/form/AdvancedForm.vue
@@ -12,7 +12,7 @@ | @@ -12,7 +12,7 @@ | ||
12 | <script lang="ts"> | 12 | <script lang="ts"> |
13 | import { defineComponent } from 'vue'; | 13 | import { defineComponent } from 'vue'; |
14 | import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; | 14 | import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; |
15 | - import { CollapseContainer } from '/@/components/Container/index'; | 15 | + import { CollapseContainer } from '/@/components/Container'; |
16 | import { PageWrapper } from '/@/components/Page'; | 16 | import { PageWrapper } from '/@/components/Page'; |
17 | 17 | ||
18 | const getSchamas = (): FormSchema[] => { | 18 | const getSchamas = (): FormSchema[] => { |
@@ -173,7 +173,12 @@ | @@ -173,7 +173,12 @@ | ||
173 | } | 173 | } |
174 | const [register1] = useForm({ | 174 | const [register1] = useForm({ |
175 | labelWidth: 120, | 175 | labelWidth: 120, |
176 | - schemas: [...getSchamas(), ...getAppendSchemas(), ...extraSchemas], | 176 | + schemas: [ |
177 | + ...getSchamas(), | ||
178 | + ...getAppendSchemas(), | ||
179 | + { field: '', component: 'Divider', label: '更多字段' }, | ||
180 | + ...extraSchemas, | ||
181 | + ], | ||
177 | actionColOptions: { | 182 | actionColOptions: { |
178 | span: 24, | 183 | span: 24, |
179 | }, | 184 | }, |
src/views/demo/form/index.vue
@@ -101,6 +101,11 @@ | @@ -101,6 +101,11 @@ | ||
101 | 101 | ||
102 | const schemas: FormSchema[] = [ | 102 | const schemas: FormSchema[] = [ |
103 | { | 103 | { |
104 | + field: '', | ||
105 | + component: 'Divider', | ||
106 | + label: '基础字段', | ||
107 | + }, | ||
108 | + { | ||
104 | field: 'field1', | 109 | field: 'field1', |
105 | component: 'Input', | 110 | component: 'Input', |
106 | label: '字段1', | 111 | label: '字段1', |
@@ -294,6 +299,11 @@ | @@ -294,6 +299,11 @@ | ||
294 | }, | 299 | }, |
295 | }, | 300 | }, |
296 | { | 301 | { |
302 | + field: '', | ||
303 | + component: 'Divider', | ||
304 | + label: '远程下拉演示', | ||
305 | + }, | ||
306 | + { | ||
297 | field: 'field30', | 307 | field: 'field30', |
298 | component: 'ApiSelect', | 308 | component: 'ApiSelect', |
299 | label: '懒加载远程下拉', | 309 | label: '懒加载远程下拉', |
@@ -363,6 +373,11 @@ | @@ -363,6 +373,11 @@ | ||
363 | }, | 373 | }, |
364 | }, | 374 | }, |
365 | { | 375 | { |
376 | + field: '', | ||
377 | + component: 'Divider', | ||
378 | + label: '其它', | ||
379 | + }, | ||
380 | + { | ||
366 | field: 'field20', | 381 | field: 'field20', |
367 | component: 'InputNumber', | 382 | component: 'InputNumber', |
368 | label: '字段20', | 383 | label: '字段20', |