Ver código fonte

feat(form): support function type of form item

vben 4 anos atrás
pai
commit
5832ee6697

+ 4 - 0
CHANGELOG.zh_CN.md

@@ -1,5 +1,9 @@
 ## Wip
 
+### ✨ Features
+
+- 表单项的`componentsProps`支持函数类型
+
 ### 🐛 Bug Fixes
 
 - 修复多个富文本编辑器只显示一个

+ 13 - 2
src/components/Drawer/src/useDrawer.ts

@@ -6,7 +6,16 @@ import type {
   UseDrawerInnerReturnType,
 } from './types';
 
-import { ref, getCurrentInstance, onUnmounted, unref, reactive, computed, watchEffect } from 'vue';
+import {
+  ref,
+  getCurrentInstance,
+  onUnmounted,
+  unref,
+  reactive,
+  computed,
+  watchEffect,
+  nextTick,
+} from 'vue';
 
 import { isProdMode } from '/@/utils/env';
 import { isFunction } from '/@/utils/is';
@@ -94,7 +103,9 @@ export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
     const data = dataTransferRef[unref(uidRef)];
     if (!data) return;
     if (!callbackFn || !isFunction(callbackFn)) return;
-    callbackFn(data);
+    nextTick(() => {
+      callbackFn(data);
+    });
   });
 
   return [

+ 1 - 0
src/components/Form/src/BasicForm.vue

@@ -4,6 +4,7 @@
       <slot name="formHeader" />
       <template v-for="schema in getSchema" :key="schema.field">
         <FormItem
+          :tableAction="tableAction"
           :schema="schema"
           :formProps="getProps"
           :allDefaultValues="defaultValueRef"

+ 19 - 11
src/components/Form/src/FormItem.tsx

@@ -2,6 +2,7 @@ import type { PropType } from 'vue';
 import type { FormProps } from './types/form';
 import type { FormSchema } from './types/form';
 import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
+import type { TableActionType } from '../../Table/src/types/table';
 
 import { defineComponent, computed, unref, toRef } from 'vue';
 import { Form, Col } from 'ant-design-vue';
@@ -37,6 +38,9 @@ export default defineComponent({
       type: Object as PropType<any>,
       default: {},
     },
+    tableAction: {
+      type: Object as PropType<TableActionType>,
+    },
   },
   setup(props, { slots }) {
     const itemLabelWidthRef = useItemLabelWidth(toRef(props, 'schema'), toRef(props, 'formProps'));
@@ -56,10 +60,19 @@ export default defineComponent({
       };
     });
 
+    const getComponentsPropsRef = computed(() => {
+      const { schema, tableAction, formModel } = props;
+      const { componentProps = {} } = schema;
+      if (!isFunction(componentProps)) {
+        return componentProps;
+      }
+      return componentProps({ schema, tableAction, formModel }) || {};
+    });
+
     const getDisableRef = computed(() => {
       const { disabled: globDisabled } = props.formProps;
-      const { dynamicDisabled, componentProps = {} } = props.schema;
-      const { disabled: itemDisabled = false } = componentProps;
+      const { dynamicDisabled } = props.schema;
+      const { disabled: itemDisabled = false } = unref(getComponentsPropsRef);
       let disabled = !!globDisabled || itemDisabled;
       if (isBoolean(dynamicDisabled)) {
         disabled = dynamicDisabled;
@@ -166,13 +179,7 @@ export default defineComponent({
     }
 
     function renderComponent() {
-      const {
-        componentProps,
-        renderComponentContent,
-        component,
-        field,
-        changeEvent = 'change',
-      } = props.schema;
+      const { renderComponentContent, component, field, changeEvent = 'change' } = props.schema;
 
       const isCheck = component && ['Switch'].includes(component);
 
@@ -192,7 +199,7 @@ export default defineComponent({
         allowClear: true,
         getPopupContainer: (trigger: Element) => trigger.parentNode,
         size,
-        ...componentProps,
+        ...unref(getComponentsPropsRef),
         disabled: unref(getDisableRef),
       };
 
@@ -201,7 +208,8 @@ export default defineComponent({
       // RangePicker place为数组
       if (isCreatePlaceholder && component !== 'RangePicker' && component) {
         placeholder =
-          (componentProps && componentProps.placeholder) || createPlaceholderMessage(component);
+          (unref(getComponentsPropsRef) && unref(getComponentsPropsRef).placeholder) ||
+          createPlaceholderMessage(component);
       }
       propsData.placeholder = placeholder;
       propsData.codeField = field;

+ 4 - 0
src/components/Form/src/props.ts

@@ -1,6 +1,7 @@
 import type { FieldMapToTime, FormSchema } from './types/form';
 import type { PropType } from 'vue';
 import type { ColEx } from './types';
+import { TableActionType } from '../../Table/src/types/table';
 
 export const basicProps = {
   model: {
@@ -103,6 +104,9 @@ export const basicProps = {
     type: String as PropType<'horizontal' | 'vertical' | 'inline'>,
     default: 'horizontal',
   },
+  tableAction: {
+    type: Object as PropType<TableActionType>,
+  },
 
   wrapperCol: Object as PropType<any>,
 

+ 4 - 1
src/components/Form/src/types/form.ts

@@ -3,6 +3,7 @@ import type { VNode } from 'vue';
 import type { BasicButtonProps } from '/@/components/Button/types';
 import type { FormItem } from './formItem';
 import type { ColEx, ComponentType } from './index';
+import { TableActionType } from '../../../Table/src/types/table';
 
 export type FieldMapToTime = [string, [string, string], string?][];
 
@@ -111,7 +112,9 @@ export interface FormSchema {
   // 组件
   component: ComponentType;
   // 组件参数
-  componentProps?: any;
+  componentProps?:
+    | ((opt: { schema: FormSchema; tableAction: TableActionType; formModel: any }) => any)
+    | object;
   // 必填
   required?: boolean;
 

+ 13 - 2
src/components/Modal/src/useModal.ts

@@ -5,7 +5,16 @@ import type {
   ReturnMethods,
   UseModalInnerReturnType,
 } from './types';
-import { ref, onUnmounted, unref, getCurrentInstance, reactive, computed, watchEffect } from 'vue';
+import {
+  ref,
+  onUnmounted,
+  unref,
+  getCurrentInstance,
+  reactive,
+  computed,
+  watchEffect,
+  nextTick,
+} from 'vue';
 import { isProdMode } from '/@/utils/env';
 import { isFunction } from '/@/utils/is';
 const dataTransferRef = reactive<any>({});
@@ -89,7 +98,9 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => {
     const data = dataTransferRef[unref(uidRef)];
     if (!data) return;
     if (!callbackFn || !isFunction(callbackFn)) return;
-    callbackFn(data);
+    nextTick(() => {
+      callbackFn(data);
+    });
   });
 
   return [

+ 2 - 0
src/components/Table/src/BasicTable.vue

@@ -11,6 +11,7 @@
       v-if="getBindValues.useSearchForm"
       :submitOnReset="true"
       :submitButtonOptions="{ loading }"
+      :tableAction="tableAction"
       @register="registerForm"
       @submit="handleSearchInfoChange"
       @advanced-change="redoHeight"
@@ -321,6 +322,7 @@
         handleTableChange,
         getRowClassName,
         wrapRef,
+        tableAction,
         ...tableAction,
       };
     },

+ 4 - 1
src/components/Table/src/components/renderEditableCell.tsx

@@ -38,7 +38,8 @@ const EditableCell = defineComponent({
       default: 'Input',
     },
   },
-  setup(props, { attrs }) {
+  emits: ['submit', 'cancel'],
+  setup(props, { attrs, emit }) {
     const table = injectTable();
     const elRef = ref<any>(null);
 
@@ -64,6 +65,7 @@ const EditableCell = defineComponent({
 
     function handleCancel() {
       isEditRef.value = false;
+      emit('cancel');
     }
 
     function handleSubmit() {
@@ -78,6 +80,7 @@ const EditableCell = defineComponent({
       const target = dataSource.find((item) => item.key === dataKey);
       if (target) {
         target[dataIndex] = unref(currentValueRef);
+        emit('submit', { dataKey, dataIndex, value: unref(currentValueRef) });
       }
     }
 

+ 5 - 7
src/views/demo/comp/drawer/Drawer4.vue

@@ -7,7 +7,7 @@
   </BasicDrawer>
 </template>
 <script lang="ts">
-  import { defineComponent, nextTick } from 'vue';
+  import { defineComponent } from 'vue';
   import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
 
   import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
@@ -42,12 +42,10 @@
         },
       });
       const [register, { receiveDrawerDataRef }] = useDrawerInner((data) => {
-        nextTick(() => {
-          // 方式1
-          setFieldsValue({
-            field2: data.data,
-            field1: data.info,
-          });
+        // 方式1
+        setFieldsValue({
+          field2: data.data,
+          field1: data.info,
         });
       });
       return { register, receiveDrawerDataRef, schemas, registerForm };

+ 11 - 13
src/views/demo/comp/modal/Modal4.vue

@@ -5,7 +5,7 @@
   </BasicModal>
 </template>
 <script lang="ts">
-  import { defineComponent, nextTick, ref } from 'vue';
+  import { defineComponent, ref } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
   const schemas: FormSchema[] = [
@@ -47,20 +47,18 @@
       });
 
       const [register, { receiveModalDataRef }] = useModalInner((data) => {
-        nextTick(() => {
-          // 方式1
-          // setFieldsValue({
-          //   field2: data.data,
-          //   field1: data.info,
-          // });
+        // 方式1
+        // setFieldsValue({
+        //   field2: data.data,
+        //   field1: data.info,
+        // });
 
-          // 方式2
-          modelRef.value = { field2: data.data, field1: data.info };
+        // 方式2
+        modelRef.value = { field2: data.data, field1: data.info };
 
-          // setProps({
-          //   model:{ field2: data.data, field1: data.info }
-          // })
-        });
+        // setProps({
+        //   model:{ field2: data.data, field1: data.info }
+        // })
       });
       return { register, receiveModalDataRef, schemas, registerForm, model: modelRef };
     },

+ 7 - 5
src/views/demo/form/index.vue

@@ -24,11 +24,13 @@
         span: 8,
       },
       defaultValue: '111',
-      componentProps: {
-        placeholder: '自定义placeholder',
-        onChange: (e: any) => {
-          console.log(e);
-        },
+      componentProps: () => {
+        return {
+          placeholder: '自定义placeholder',
+          onChange: (e: any) => {
+            console.log(e);
+          },
+        };
       },
     },
     {