浏览代码

feat(form): add `Divider` for schema component type

新增Divider用于较长表单的区域分割
无木 3 年之前
父节点
当前提交
47a448b8ae

+ 8 - 0
CHANGELOG.zh_CN.md

@@ -1,3 +1,11 @@
+### ✨ Features
+
+- **BasicForm** 表单组件新增`Divider`,用于较长表单的区域分割
+
+### 🐛 Bug Fixes
+
+- **其它** 修复部分封装组件在使用插槽时报错的问题
+
 ## 2.7.1(2021-08-16)
 
 - 升级 vue 3.2,如果运行失败,删除 node_modules 后重装即可

+ 6 - 2
src/components/Form/src/BasicForm.vue

@@ -29,7 +29,7 @@
           #[item]="data"
           v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']"
         >
-          <slot :name="item" v-bind="data"></slot>
+          <slot :name="item" v-bind="data || {}"></slot>
         </template>
       </FormAction>
       <slot name="formFooter"></slot>
@@ -132,7 +132,11 @@
             }
           }
         }
-        return schemas as FormSchema[];
+        if (unref(getProps).showAdvancedButton) {
+          return schemas.filter((schema) => schema.component !== 'Divider') as FormSchema[];
+        } else {
+          return schemas as FormSchema[];
+        }
       });
 
       const { handleToggleAdvanced } = useAdvanced({

+ 2 - 0
src/components/Form/src/componentMap.ts

@@ -18,6 +18,7 @@ import {
   TreeSelect,
   Slider,
   Rate,
+  Divider,
 } from 'ant-design-vue';
 
 import RadioButtonGroup from './components/RadioButtonGroup.vue';
@@ -61,6 +62,7 @@ componentMap.set('IconPicker', IconPicker);
 componentMap.set('InputCountDown', CountdownInput);
 
 componentMap.set('Upload', BasicUpload);
+componentMap.set('Divider', Divider);
 
 export function add(compName: ComponentType, component: Component) {
   componentMap.set(compName, component);

+ 48 - 34
src/components/Form/src/components/FormItem.vue

@@ -5,7 +5,7 @@
   import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
   import type { TableActionType } from '/@/components/Table';
   import { defineComponent, computed, unref, toRefs } from 'vue';
-  import { Form, Col } from 'ant-design-vue';
+  import { Form, Col, Divider } from 'ant-design-vue';
   import { componentMap } from '../componentMap';
   import { BasicHelp } from '/@/components/Basic';
   import { isBoolean, isFunction, isNull } from '/@/utils/is';
@@ -73,11 +73,17 @@
 
       const getComponentsProps = computed(() => {
         const { schema, tableAction, formModel, formActionType } = props;
-        const { componentProps = {} } = schema;
-        if (!isFunction(componentProps)) {
-          return componentProps;
+        let { componentProps = {} } = schema;
+        if (isFunction(componentProps)) {
+          componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
         }
-        return componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
+        if (schema.component === 'Divider') {
+          componentProps = Object.assign({ type: 'horizontal' }, componentProps, {
+            orientation: 'left',
+            plain: true,
+          });
+        }
+        return componentProps;
       });
 
       const getDisable = computed(() => {
@@ -300,38 +306,46 @@
       }
 
       function renderItem() {
-        const { itemProps, slot, render, field, suffix } = props.schema;
+        const { itemProps, slot, render, field, suffix, component, label } = props.schema;
         const { labelCol, wrapperCol } = unref(itemLabelWidthProp);
         const { colon } = props.formProps;
 
-        const getContent = () => {
-          return slot
-            ? getSlot(slots, slot, unref(getValues))
-            : render
-            ? render(unref(getValues))
-            : renderComponent();
-        };
-
-        const showSuffix = !!suffix;
-        const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
-
-        return (
-          <Form.Item
-            name={field}
-            colon={colon}
-            class={{ 'suffix-item': showSuffix }}
-            {...(itemProps as Recordable)}
-            label={renderLabelHelpMessage()}
-            rules={handleRules()}
-            labelCol={labelCol}
-            wrapperCol={wrapperCol}
-          >
-            <div style="display:flex">
-              <div style="flex:1">{getContent()}</div>
-              {showSuffix && <span class="suffix">{getSuffix}</span>}
-            </div>
-          </Form.Item>
-        );
+        if (component === 'Divider') {
+          return (
+            <Col span={24}>
+              <Divider {...unref(getComponentsProps)}>{label}</Divider>
+            </Col>
+          );
+        } else {
+          const getContent = () => {
+            return slot
+              ? getSlot(slots, slot, unref(getValues))
+              : render
+              ? render(unref(getValues))
+              : renderComponent();
+          };
+
+          const showSuffix = !!suffix;
+          const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
+
+          return (
+            <Form.Item
+              name={field}
+              colon={colon}
+              class={{ 'suffix-item': showSuffix }}
+              {...(itemProps as Recordable)}
+              label={renderLabelHelpMessage()}
+              rules={handleRules()}
+              labelCol={labelCol}
+              wrapperCol={wrapperCol}
+            >
+              <div style="display:flex">
+                <div style="flex:1">{getContent()}</div>
+                {showSuffix && <span class="suffix">{getSuffix}</span>}
+              </div>
+            </Form.Item>
+          );
+        }
       }
 
       return () => {

+ 6 - 2
src/components/Form/src/hooks/useFormEvents.ts

@@ -149,7 +149,9 @@ export function useFormEvents({
       updateData = [...data];
     }
 
-    const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
+    const hasField = updateData.every(
+      (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field)
+    );
 
     if (!hasField) {
       error(
@@ -169,7 +171,9 @@ export function useFormEvents({
       updateData = [...data];
     }
 
-    const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
+    const hasField = updateData.every(
+      (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field)
+    );
 
     if (!hasField) {
       error(

+ 2 - 1
src/components/Form/src/types/index.ts

@@ -109,4 +109,5 @@ export type ComponentType =
   | 'IconPicker'
   | 'Render'
   | 'Slider'
-  | 'Rate';
+  | 'Rate'
+  | 'Divider';

+ 7 - 2
src/views/demo/form/AdvancedForm.vue

@@ -12,7 +12,7 @@
 <script lang="ts">
   import { defineComponent } from 'vue';
   import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
-  import { CollapseContainer } from '/@/components/Container/index';
+  import { CollapseContainer } from '/@/components/Container';
   import { PageWrapper } from '/@/components/Page';
 
   const getSchamas = (): FormSchema[] => {
@@ -173,7 +173,12 @@
       }
       const [register1] = useForm({
         labelWidth: 120,
-        schemas: [...getSchamas(), ...getAppendSchemas(), ...extraSchemas],
+        schemas: [
+          ...getSchamas(),
+          ...getAppendSchemas(),
+          { field: '', component: 'Divider', label: '更多字段' },
+          ...extraSchemas,
+        ],
         actionColOptions: {
           span: 24,
         },

+ 15 - 0
src/views/demo/form/index.vue

@@ -100,6 +100,11 @@
   };
 
   const schemas: FormSchema[] = [
+    {
+      field: '',
+      component: 'Divider',
+      label: '基础字段',
+    },
     {
       field: 'field1',
       component: 'Input',
@@ -293,6 +298,11 @@
         ],
       },
     },
+    {
+      field: '',
+      component: 'Divider',
+      label: '远程下拉演示',
+    },
     {
       field: 'field30',
       component: 'ApiSelect',
@@ -362,6 +372,11 @@
         span: 8,
       },
     },
+    {
+      field: '',
+      component: 'Divider',
+      label: '其它',
+    },
     {
       field: 'field20',
       component: 'InputNumber',