Browse Source

perf(drawer): perf drawer

vben 4 years ago
parent
commit
28f7f7bf7f

+ 5 - 0
CHANGELOG.zh_CN.md

@@ -5,9 +5,14 @@
 - 表单组件现在支持直接传入 model 直接进行 set 操作,参考**组件->弹窗扩展->打开弹窗并传递数据**
 
 - modal 的 useModalInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值,
+
   - 用于处理打开弹窗对表单等组件的设置值。参考**组件->弹窗扩展->打开弹窗并传递数据**
   - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。
 
+- drawer 的 useDrawerInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值,
+  - 用于处理打开抽屉对表单等组件的设置值。参考**组件->抽屉扩展->打开抽屉并传递数据**
+  - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。
+
 ### ✨ Refactor
 
 - 表单代码优化重构

+ 13 - 17
src/components/Drawer/src/BasicDrawer.tsx

@@ -1,17 +1,19 @@
-import { Drawer, Row, Col, Button } from 'ant-design-vue';
+import type { DrawerInstance, DrawerProps } from './types';
+
 import { defineComponent, ref, computed, watchEffect, watch, unref, nextTick, toRaw } from 'vue';
+import { Drawer, Row, Col, Button } from 'ant-design-vue';
+
 import { BasicTitle } from '/@/components/Basic';
 import { FullLoading } from '/@/components/Loading/index';
-
-import { getSlot } from '/@/utils/helper/tsxHelper';
-
-import { DrawerInstance, DrawerProps } from './types';
+import { LeftOutlined } from '@ant-design/icons-vue';
 
 import { basicProps } from './props';
+
+import { getSlot } from '/@/utils/helper/tsxHelper';
 import { isFunction, isNumber } from '/@/utils/is';
-import { LeftOutlined } from '@ant-design/icons-vue';
 import { buildUUID } from '/@/utils/uuid';
 import { deepMerge } from '/@/utils';
+
 import './index.less';
 
 const prefixCls = 'basic-drawer';
@@ -31,7 +33,6 @@ export default defineComponent({
 
     const getProps = computed(() => {
       const opt: any = {
-        // @ts-ignore
         placement: 'right',
         ...attrs,
         ...props,
@@ -47,7 +48,6 @@ export default defineComponent({
         opt.wrapClassName = opt.wrapClassName
           ? `${opt.wrapClassName} ${prefixCls}__detail`
           : `${prefixCls}__detail`;
-        // opt.maskClosable = false;
         if (!opt.getContainer) {
           opt.getContainer = `.default-layout__main`;
         }
@@ -128,11 +128,11 @@ export default defineComponent({
             {showOkBtn && (
               <Button
                 type={okType}
-                {...okButtonProps}
-                loading={confirmLoading}
                 onClick={() => {
                   emit('ok');
                 }}
+                {...okButtonProps}
+                loading={confirmLoading}
               >
                 {() => okText}
               </Button>
@@ -152,13 +152,9 @@ export default defineComponent({
             {() => (
               <>
                 {props.showDetailBack && (
-                  <Col class="mx-2">
-                    {() => (
-                      <Button size="small" type="link" onClick={onClose}>
-                        {() => <LeftOutlined />}
-                      </Button>
-                    )}
-                  </Col>
+                  <Button size="small" type="link" onClick={onClose}>
+                    {() => <LeftOutlined />}
+                  </Button>
                 )}
 
                 {title && (

+ 3 - 0
src/components/Drawer/src/types.ts

@@ -5,10 +5,12 @@ import type { ScrollContainerOptions } from '/@/components/Container/index';
 export interface DrawerInstance {
   setDrawerProps: (props: Partial<DrawerProps> | boolean) => void;
 }
+
 export interface ReturnMethods extends DrawerInstance {
   openDrawer: (visible?: boolean) => void;
   transferDrawerData: (data: any) => void;
 }
+
 export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void;
 
 export interface ReturnInnerMethods extends DrawerInstance {
@@ -19,6 +21,7 @@ export interface ReturnInnerMethods extends DrawerInstance {
 }
 
 export type UseDrawerReturnType = [RegisterFn, ReturnMethods];
+
 export type UseDrawerInnerReturnType = [RegisterFn, ReturnInnerMethods];
 
 export interface DrawerFooterProps {

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

@@ -5,8 +5,11 @@ import type {
   DrawerProps,
   UseDrawerInnerReturnType,
 } from './types';
-import { ref, getCurrentInstance, onUnmounted, unref, reactive, computed } from 'vue';
+
+import { ref, getCurrentInstance, onUnmounted, unref, reactive, computed, watchEffect } from 'vue';
+
 import { isProdMode } from '/@/utils/env';
+import { isFunction } from '/@/utils/is';
 
 const dataTransferRef = reactive<any>({});
 /**
@@ -34,6 +37,7 @@ export function useDrawer(): UseDrawerReturnType {
     drawerRef.value = drawerInstance;
     loadedRef.value = true;
   }
+
   const getInstance = () => {
     const instance = unref(drawerRef);
     if (!instance) {
@@ -41,15 +45,18 @@ export function useDrawer(): UseDrawerReturnType {
     }
     return instance;
   };
+
   const methods: ReturnMethods = {
     setDrawerProps: (props: Partial<DrawerProps>): void => {
       getInstance().setDrawerProps(props);
     },
+
     openDrawer: (visible = true): void => {
       getInstance().setDrawerProps({
         visible: visible,
       });
     },
+
     transferDrawerData(val: any) {
       dataTransferRef[unref(uidRef)] = val;
     },
@@ -57,7 +64,7 @@ export function useDrawer(): UseDrawerReturnType {
 
   return [getDrawer, methods];
 }
-export const useDrawerInner = (): UseDrawerInnerReturnType => {
+export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
   const drawerInstanceRef = ref<DrawerInstance | null>(null);
   const currentInstall = getCurrentInstance();
   const uidRef = ref<string>('');
@@ -65,6 +72,7 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => {
   if (!currentInstall) {
     throw new Error('instance is undefined!');
   }
+
   const getInstance = () => {
     const instance = unref(drawerInstanceRef);
     if (!instance) {
@@ -72,26 +80,39 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => {
     }
     return instance;
   };
+
   const register = (modalInstance: DrawerInstance, uuid: string) => {
     uidRef.value = uuid;
     drawerInstanceRef.value = modalInstance;
     currentInstall.emit('register', modalInstance);
   };
+
+  watchEffect(() => {
+    const data = dataTransferRef[unref(uidRef)];
+    if (!data) return;
+    if (!callbackFn || !isFunction(callbackFn)) return;
+    callbackFn(data);
+  });
+
   return [
     register,
     {
       receiveDrawerDataRef: computed(() => {
         return dataTransferRef[unref(uidRef)];
       }),
+
       changeLoading: (loading = true) => {
         getInstance().setDrawerProps({ loading });
       },
+
       changeOkLoading: (loading = true) => {
         getInstance().setDrawerProps({ confirmLoading: loading });
       },
+
       closeDrawer: () => {
         getInstance().setDrawerProps({ visible: false });
       },
+
       setDrawerProps: (props: Partial<DrawerProps>) => {
         getInstance().setDrawerProps(props);
       },

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

@@ -1,16 +1,56 @@
 <template>
   <BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="50%">
-    <p class="h-20">外部传递数据: {{ receiveDrawerDataRef }}</p>
+    <div :style="{ background: '#fff' }">
+      <p class="h-20">外部传递数据: {{ receiveDrawerDataRef }}</p>
+      <BasicForm @register="registerForm" />
+    </div>
   </BasicDrawer>
 </template>
 <script lang="ts">
-  import { defineComponent } from 'vue';
+  import { defineComponent, nextTick } from 'vue';
   import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  const schemas: FormSchema[] = [
+    {
+      field: 'field1',
+      component: 'Input',
+      label: '字段1',
+      colProps: {
+        span: 12,
+      },
+      defaultValue: '111',
+    },
+    {
+      field: 'field2',
+      component: 'Input',
+      label: '字段2',
+      colProps: {
+        span: 12,
+      },
+    },
+  ];
   export default defineComponent({
-    components: { BasicDrawer },
+    components: { BasicDrawer, BasicForm },
     setup() {
-      const [register, { receiveDrawerDataRef }] = useDrawerInner();
-      return { register, receiveDrawerDataRef };
+      const [registerForm, { setFieldsValue }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      const [register, { receiveDrawerDataRef }] = useDrawerInner((data) => {
+        nextTick(() => {
+          // 方式1
+          setFieldsValue({
+            field2: data.data,
+            field1: data.info,
+          });
+        });
+      });
+      return { register, receiveDrawerDataRef, schemas, registerForm };
     },
   });
 </script>

+ 10 - 11
src/views/demo/comp/drawer/index.vue

@@ -1,21 +1,20 @@
 <template>
-  <div class="px-10">
-    <Alert message="使用 useDrawer 进行抽屉操作" show-icon class="my-4" />
-    <a-button type="primary" class="mr-2" @click="openDrawerLoading">打开Drawer</a-button>
+  <div class="px-10 py-4">
+    <Alert message="使用 useDrawer 进行抽屉操作" show-icon />
+    <a-button type="primary" class="my-4" @click="openDrawerLoading">打开Drawer</a-button>
 
-    <Alert message="内外同时同时显示隐藏" show-icon class="my-4" />
-    <a-button type="primary" class="mr-2" @click="openDrawer2">打开Drawer</a-button>
-    <Alert message="自适应高度/显示footer" show-icon class="my-4" />
-    <a-button type="primary" class="mr-2" @click="openDrawer3">打开Drawer</a-button>
+    <Alert message="内外同时同时显示隐藏" show-icon />
+    <a-button type="primary" class="my-4" @click="openDrawer2">打开Drawer</a-button>
+    <Alert message="自适应高度/显示footer" show-icon />
+    <a-button type="primary" class="my-4" @click="openDrawer3">打开Drawer</a-button>
 
     <Alert
       message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式"
       show-icon
-      class="my-4"
     />
-    <a-button type="primary" class="mr-2" @click="send">打开Drawer并传递数据</a-button>
-    <Alert message="详情页模式" show-icon class="my-4" />
-    <a-button type="primary" class="mr-2" @click="openDrawer5">打开详情Drawer</a-button>
+    <a-button type="primary" class="my-4" @click="send">打开Drawer并传递数据</a-button>
+    <Alert message="详情页模式" show-icon />
+    <a-button type="primary" class="my-4" @click="openDrawer5">打开详情Drawer</a-button>
     <Drawer1 @register="register1" />
     <Drawer2 @register="register2" />
     <Drawer3 @register="register3" />

+ 7 - 9
src/views/demo/comp/modal/index.vue

@@ -1,26 +1,24 @@
 <template>
-  <div class="px-10">
+  <div class="px-10 py-4">
     <Alert
       message="使用 useModal 进行弹窗操作,默认可以拖动,可以通过 draggable
     参数进行控制是否可以拖动/全屏"
       show-icon
-      class="my-4"
     />
-    <a-button type="primary" class="mr-2" @click="openModalLoading"
+    <a-button type="primary" class="my-4" @click="openModalLoading"
       >打开弹窗 默认可以拖动/全屏</a-button
     >
 
-    <Alert message="内外同时同时显示隐藏" show-icon class="my-4" />
-    <a-button type="primary" class="mr-2" @click="openModal2">打开弹窗</a-button>
-    <Alert message="自适应高度" show-icon class="my-4" />
-    <a-button type="primary" class="mr-2" @click="openModal3">打开弹窗</a-button>
+    <Alert message="内外同时同时显示隐藏" show-icon />
+    <a-button type="primary" class="my-4" @click="openModal2">打开弹窗</a-button>
+    <Alert message="自适应高度" show-icon />
+    <a-button type="primary" class="my-4" @click="openModal3">打开弹窗</a-button>
 
     <Alert
       message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式"
       show-icon
-      class="my-4"
     />
-    <a-button type="primary" class="mr-2" @click="send">打开弹窗并传递数据</a-button>
+    <a-button type="primary" class="my-4" @click="send">打开弹窗并传递数据</a-button>
 
     <Modal1 @register="register1" />
     <Modal2 @register="register2" />