Commit 28f7f7bf7f3ae49759b44395f6b06c2c61359d04
1 parent
840332ab
perf(drawer): perf drawer
Showing
7 changed files
with
106 additions
and
44 deletions
CHANGELOG.zh_CN.md
@@ -5,9 +5,14 @@ | @@ -5,9 +5,14 @@ | ||
5 | - 表单组件现在支持直接传入 model 直接进行 set 操作,参考**组件->弹窗扩展->打开弹窗并传递数据** | 5 | - 表单组件现在支持直接传入 model 直接进行 set 操作,参考**组件->弹窗扩展->打开弹窗并传递数据** |
6 | 6 | ||
7 | - modal 的 useModalInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值, | 7 | - modal 的 useModalInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值, |
8 | + | ||
8 | - 用于处理打开弹窗对表单等组件的设置值。参考**组件->弹窗扩展->打开弹窗并传递数据** | 9 | - 用于处理打开弹窗对表单等组件的设置值。参考**组件->弹窗扩展->打开弹窗并传递数据** |
9 | - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。 | 10 | - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。 |
10 | 11 | ||
12 | +- drawer 的 useDrawerInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值, | ||
13 | + - 用于处理打开抽屉对表单等组件的设置值。参考**组件->抽屉扩展->打开抽屉并传递数据** | ||
14 | + - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。 | ||
15 | + | ||
11 | ### ✨ Refactor | 16 | ### ✨ Refactor |
12 | 17 | ||
13 | - 表单代码优化重构 | 18 | - 表单代码优化重构 |
src/components/Drawer/src/BasicDrawer.tsx
1 | -import { Drawer, Row, Col, Button } from 'ant-design-vue'; | 1 | +import type { DrawerInstance, DrawerProps } from './types'; |
2 | + | ||
2 | import { defineComponent, ref, computed, watchEffect, watch, unref, nextTick, toRaw } from 'vue'; | 3 | import { defineComponent, ref, computed, watchEffect, watch, unref, nextTick, toRaw } from 'vue'; |
4 | +import { Drawer, Row, Col, Button } from 'ant-design-vue'; | ||
5 | + | ||
3 | import { BasicTitle } from '/@/components/Basic'; | 6 | import { BasicTitle } from '/@/components/Basic'; |
4 | import { FullLoading } from '/@/components/Loading/index'; | 7 | import { FullLoading } from '/@/components/Loading/index'; |
5 | - | ||
6 | -import { getSlot } from '/@/utils/helper/tsxHelper'; | ||
7 | - | ||
8 | -import { DrawerInstance, DrawerProps } from './types'; | 8 | +import { LeftOutlined } from '@ant-design/icons-vue'; |
9 | 9 | ||
10 | import { basicProps } from './props'; | 10 | import { basicProps } from './props'; |
11 | + | ||
12 | +import { getSlot } from '/@/utils/helper/tsxHelper'; | ||
11 | import { isFunction, isNumber } from '/@/utils/is'; | 13 | import { isFunction, isNumber } from '/@/utils/is'; |
12 | -import { LeftOutlined } from '@ant-design/icons-vue'; | ||
13 | import { buildUUID } from '/@/utils/uuid'; | 14 | import { buildUUID } from '/@/utils/uuid'; |
14 | import { deepMerge } from '/@/utils'; | 15 | import { deepMerge } from '/@/utils'; |
16 | + | ||
15 | import './index.less'; | 17 | import './index.less'; |
16 | 18 | ||
17 | const prefixCls = 'basic-drawer'; | 19 | const prefixCls = 'basic-drawer'; |
@@ -31,7 +33,6 @@ export default defineComponent({ | @@ -31,7 +33,6 @@ export default defineComponent({ | ||
31 | 33 | ||
32 | const getProps = computed(() => { | 34 | const getProps = computed(() => { |
33 | const opt: any = { | 35 | const opt: any = { |
34 | - // @ts-ignore | ||
35 | placement: 'right', | 36 | placement: 'right', |
36 | ...attrs, | 37 | ...attrs, |
37 | ...props, | 38 | ...props, |
@@ -47,7 +48,6 @@ export default defineComponent({ | @@ -47,7 +48,6 @@ export default defineComponent({ | ||
47 | opt.wrapClassName = opt.wrapClassName | 48 | opt.wrapClassName = opt.wrapClassName |
48 | ? `${opt.wrapClassName} ${prefixCls}__detail` | 49 | ? `${opt.wrapClassName} ${prefixCls}__detail` |
49 | : `${prefixCls}__detail`; | 50 | : `${prefixCls}__detail`; |
50 | - // opt.maskClosable = false; | ||
51 | if (!opt.getContainer) { | 51 | if (!opt.getContainer) { |
52 | opt.getContainer = `.default-layout__main`; | 52 | opt.getContainer = `.default-layout__main`; |
53 | } | 53 | } |
@@ -128,11 +128,11 @@ export default defineComponent({ | @@ -128,11 +128,11 @@ export default defineComponent({ | ||
128 | {showOkBtn && ( | 128 | {showOkBtn && ( |
129 | <Button | 129 | <Button |
130 | type={okType} | 130 | type={okType} |
131 | - {...okButtonProps} | ||
132 | - loading={confirmLoading} | ||
133 | onClick={() => { | 131 | onClick={() => { |
134 | emit('ok'); | 132 | emit('ok'); |
135 | }} | 133 | }} |
134 | + {...okButtonProps} | ||
135 | + loading={confirmLoading} | ||
136 | > | 136 | > |
137 | {() => okText} | 137 | {() => okText} |
138 | </Button> | 138 | </Button> |
@@ -152,13 +152,9 @@ export default defineComponent({ | @@ -152,13 +152,9 @@ export default defineComponent({ | ||
152 | {() => ( | 152 | {() => ( |
153 | <> | 153 | <> |
154 | {props.showDetailBack && ( | 154 | {props.showDetailBack && ( |
155 | - <Col class="mx-2"> | ||
156 | - {() => ( | ||
157 | - <Button size="small" type="link" onClick={onClose}> | ||
158 | - {() => <LeftOutlined />} | ||
159 | - </Button> | ||
160 | - )} | ||
161 | - </Col> | 155 | + <Button size="small" type="link" onClick={onClose}> |
156 | + {() => <LeftOutlined />} | ||
157 | + </Button> | ||
162 | )} | 158 | )} |
163 | 159 | ||
164 | {title && ( | 160 | {title && ( |
src/components/Drawer/src/types.ts
@@ -5,10 +5,12 @@ import type { ScrollContainerOptions } from '/@/components/Container/index'; | @@ -5,10 +5,12 @@ import type { ScrollContainerOptions } from '/@/components/Container/index'; | ||
5 | export interface DrawerInstance { | 5 | export interface DrawerInstance { |
6 | setDrawerProps: (props: Partial<DrawerProps> | boolean) => void; | 6 | setDrawerProps: (props: Partial<DrawerProps> | boolean) => void; |
7 | } | 7 | } |
8 | + | ||
8 | export interface ReturnMethods extends DrawerInstance { | 9 | export interface ReturnMethods extends DrawerInstance { |
9 | openDrawer: (visible?: boolean) => void; | 10 | openDrawer: (visible?: boolean) => void; |
10 | transferDrawerData: (data: any) => void; | 11 | transferDrawerData: (data: any) => void; |
11 | } | 12 | } |
13 | + | ||
12 | export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void; | 14 | export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void; |
13 | 15 | ||
14 | export interface ReturnInnerMethods extends DrawerInstance { | 16 | export interface ReturnInnerMethods extends DrawerInstance { |
@@ -19,6 +21,7 @@ export interface ReturnInnerMethods extends DrawerInstance { | @@ -19,6 +21,7 @@ export interface ReturnInnerMethods extends DrawerInstance { | ||
19 | } | 21 | } |
20 | 22 | ||
21 | export type UseDrawerReturnType = [RegisterFn, ReturnMethods]; | 23 | export type UseDrawerReturnType = [RegisterFn, ReturnMethods]; |
24 | + | ||
22 | export type UseDrawerInnerReturnType = [RegisterFn, ReturnInnerMethods]; | 25 | export type UseDrawerInnerReturnType = [RegisterFn, ReturnInnerMethods]; |
23 | 26 | ||
24 | export interface DrawerFooterProps { | 27 | export interface DrawerFooterProps { |
src/components/Drawer/src/useDrawer.ts
@@ -5,8 +5,11 @@ import type { | @@ -5,8 +5,11 @@ import type { | ||
5 | DrawerProps, | 5 | DrawerProps, |
6 | UseDrawerInnerReturnType, | 6 | UseDrawerInnerReturnType, |
7 | } from './types'; | 7 | } from './types'; |
8 | -import { ref, getCurrentInstance, onUnmounted, unref, reactive, computed } from 'vue'; | 8 | + |
9 | +import { ref, getCurrentInstance, onUnmounted, unref, reactive, computed, watchEffect } from 'vue'; | ||
10 | + | ||
9 | import { isProdMode } from '/@/utils/env'; | 11 | import { isProdMode } from '/@/utils/env'; |
12 | +import { isFunction } from '/@/utils/is'; | ||
10 | 13 | ||
11 | const dataTransferRef = reactive<any>({}); | 14 | const dataTransferRef = reactive<any>({}); |
12 | /** | 15 | /** |
@@ -34,6 +37,7 @@ export function useDrawer(): UseDrawerReturnType { | @@ -34,6 +37,7 @@ export function useDrawer(): UseDrawerReturnType { | ||
34 | drawerRef.value = drawerInstance; | 37 | drawerRef.value = drawerInstance; |
35 | loadedRef.value = true; | 38 | loadedRef.value = true; |
36 | } | 39 | } |
40 | + | ||
37 | const getInstance = () => { | 41 | const getInstance = () => { |
38 | const instance = unref(drawerRef); | 42 | const instance = unref(drawerRef); |
39 | if (!instance) { | 43 | if (!instance) { |
@@ -41,15 +45,18 @@ export function useDrawer(): UseDrawerReturnType { | @@ -41,15 +45,18 @@ export function useDrawer(): UseDrawerReturnType { | ||
41 | } | 45 | } |
42 | return instance; | 46 | return instance; |
43 | }; | 47 | }; |
48 | + | ||
44 | const methods: ReturnMethods = { | 49 | const methods: ReturnMethods = { |
45 | setDrawerProps: (props: Partial<DrawerProps>): void => { | 50 | setDrawerProps: (props: Partial<DrawerProps>): void => { |
46 | getInstance().setDrawerProps(props); | 51 | getInstance().setDrawerProps(props); |
47 | }, | 52 | }, |
53 | + | ||
48 | openDrawer: (visible = true): void => { | 54 | openDrawer: (visible = true): void => { |
49 | getInstance().setDrawerProps({ | 55 | getInstance().setDrawerProps({ |
50 | visible: visible, | 56 | visible: visible, |
51 | }); | 57 | }); |
52 | }, | 58 | }, |
59 | + | ||
53 | transferDrawerData(val: any) { | 60 | transferDrawerData(val: any) { |
54 | dataTransferRef[unref(uidRef)] = val; | 61 | dataTransferRef[unref(uidRef)] = val; |
55 | }, | 62 | }, |
@@ -57,7 +64,7 @@ export function useDrawer(): UseDrawerReturnType { | @@ -57,7 +64,7 @@ export function useDrawer(): UseDrawerReturnType { | ||
57 | 64 | ||
58 | return [getDrawer, methods]; | 65 | return [getDrawer, methods]; |
59 | } | 66 | } |
60 | -export const useDrawerInner = (): UseDrawerInnerReturnType => { | 67 | +export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => { |
61 | const drawerInstanceRef = ref<DrawerInstance | null>(null); | 68 | const drawerInstanceRef = ref<DrawerInstance | null>(null); |
62 | const currentInstall = getCurrentInstance(); | 69 | const currentInstall = getCurrentInstance(); |
63 | const uidRef = ref<string>(''); | 70 | const uidRef = ref<string>(''); |
@@ -65,6 +72,7 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => { | @@ -65,6 +72,7 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => { | ||
65 | if (!currentInstall) { | 72 | if (!currentInstall) { |
66 | throw new Error('instance is undefined!'); | 73 | throw new Error('instance is undefined!'); |
67 | } | 74 | } |
75 | + | ||
68 | const getInstance = () => { | 76 | const getInstance = () => { |
69 | const instance = unref(drawerInstanceRef); | 77 | const instance = unref(drawerInstanceRef); |
70 | if (!instance) { | 78 | if (!instance) { |
@@ -72,26 +80,39 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => { | @@ -72,26 +80,39 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => { | ||
72 | } | 80 | } |
73 | return instance; | 81 | return instance; |
74 | }; | 82 | }; |
83 | + | ||
75 | const register = (modalInstance: DrawerInstance, uuid: string) => { | 84 | const register = (modalInstance: DrawerInstance, uuid: string) => { |
76 | uidRef.value = uuid; | 85 | uidRef.value = uuid; |
77 | drawerInstanceRef.value = modalInstance; | 86 | drawerInstanceRef.value = modalInstance; |
78 | currentInstall.emit('register', modalInstance); | 87 | currentInstall.emit('register', modalInstance); |
79 | }; | 88 | }; |
89 | + | ||
90 | + watchEffect(() => { | ||
91 | + const data = dataTransferRef[unref(uidRef)]; | ||
92 | + if (!data) return; | ||
93 | + if (!callbackFn || !isFunction(callbackFn)) return; | ||
94 | + callbackFn(data); | ||
95 | + }); | ||
96 | + | ||
80 | return [ | 97 | return [ |
81 | register, | 98 | register, |
82 | { | 99 | { |
83 | receiveDrawerDataRef: computed(() => { | 100 | receiveDrawerDataRef: computed(() => { |
84 | return dataTransferRef[unref(uidRef)]; | 101 | return dataTransferRef[unref(uidRef)]; |
85 | }), | 102 | }), |
103 | + | ||
86 | changeLoading: (loading = true) => { | 104 | changeLoading: (loading = true) => { |
87 | getInstance().setDrawerProps({ loading }); | 105 | getInstance().setDrawerProps({ loading }); |
88 | }, | 106 | }, |
107 | + | ||
89 | changeOkLoading: (loading = true) => { | 108 | changeOkLoading: (loading = true) => { |
90 | getInstance().setDrawerProps({ confirmLoading: loading }); | 109 | getInstance().setDrawerProps({ confirmLoading: loading }); |
91 | }, | 110 | }, |
111 | + | ||
92 | closeDrawer: () => { | 112 | closeDrawer: () => { |
93 | getInstance().setDrawerProps({ visible: false }); | 113 | getInstance().setDrawerProps({ visible: false }); |
94 | }, | 114 | }, |
115 | + | ||
95 | setDrawerProps: (props: Partial<DrawerProps>) => { | 116 | setDrawerProps: (props: Partial<DrawerProps>) => { |
96 | getInstance().setDrawerProps(props); | 117 | getInstance().setDrawerProps(props); |
97 | }, | 118 | }, |
src/views/demo/comp/drawer/Drawer4.vue
1 | <template> | 1 | <template> |
2 | <BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="50%"> | 2 | <BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="50%"> |
3 | - <p class="h-20">外部传递数据: {{ receiveDrawerDataRef }}</p> | 3 | + <div :style="{ background: '#fff' }"> |
4 | + <p class="h-20">外部传递数据: {{ receiveDrawerDataRef }}</p> | ||
5 | + <BasicForm @register="registerForm" /> | ||
6 | + </div> | ||
4 | </BasicDrawer> | 7 | </BasicDrawer> |
5 | </template> | 8 | </template> |
6 | <script lang="ts"> | 9 | <script lang="ts"> |
7 | - import { defineComponent } from 'vue'; | 10 | + import { defineComponent, nextTick } from 'vue'; |
8 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | 11 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
12 | + | ||
13 | + import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; | ||
14 | + const schemas: FormSchema[] = [ | ||
15 | + { | ||
16 | + field: 'field1', | ||
17 | + component: 'Input', | ||
18 | + label: '字段1', | ||
19 | + colProps: { | ||
20 | + span: 12, | ||
21 | + }, | ||
22 | + defaultValue: '111', | ||
23 | + }, | ||
24 | + { | ||
25 | + field: 'field2', | ||
26 | + component: 'Input', | ||
27 | + label: '字段2', | ||
28 | + colProps: { | ||
29 | + span: 12, | ||
30 | + }, | ||
31 | + }, | ||
32 | + ]; | ||
9 | export default defineComponent({ | 33 | export default defineComponent({ |
10 | - components: { BasicDrawer }, | 34 | + components: { BasicDrawer, BasicForm }, |
11 | setup() { | 35 | setup() { |
12 | - const [register, { receiveDrawerDataRef }] = useDrawerInner(); | ||
13 | - return { register, receiveDrawerDataRef }; | 36 | + const [registerForm, { setFieldsValue }] = useForm({ |
37 | + labelWidth: 120, | ||
38 | + schemas, | ||
39 | + showActionButtonGroup: false, | ||
40 | + actionColOptions: { | ||
41 | + span: 24, | ||
42 | + }, | ||
43 | + }); | ||
44 | + const [register, { receiveDrawerDataRef }] = useDrawerInner((data) => { | ||
45 | + nextTick(() => { | ||
46 | + // 方式1 | ||
47 | + setFieldsValue({ | ||
48 | + field2: data.data, | ||
49 | + field1: data.info, | ||
50 | + }); | ||
51 | + }); | ||
52 | + }); | ||
53 | + return { register, receiveDrawerDataRef, schemas, registerForm }; | ||
14 | }, | 54 | }, |
15 | }); | 55 | }); |
16 | </script> | 56 | </script> |
src/views/demo/comp/drawer/index.vue
1 | <template> | 1 | <template> |
2 | - <div class="px-10"> | ||
3 | - <Alert message="使用 useDrawer 进行抽屉操作" show-icon class="my-4" /> | ||
4 | - <a-button type="primary" class="mr-2" @click="openDrawerLoading">打开Drawer</a-button> | 2 | + <div class="px-10 py-4"> |
3 | + <Alert message="使用 useDrawer 进行抽屉操作" show-icon /> | ||
4 | + <a-button type="primary" class="my-4" @click="openDrawerLoading">打开Drawer</a-button> | ||
5 | 5 | ||
6 | - <Alert message="内外同时同时显示隐藏" show-icon class="my-4" /> | ||
7 | - <a-button type="primary" class="mr-2" @click="openDrawer2">打开Drawer</a-button> | ||
8 | - <Alert message="自适应高度/显示footer" show-icon class="my-4" /> | ||
9 | - <a-button type="primary" class="mr-2" @click="openDrawer3">打开Drawer</a-button> | 6 | + <Alert message="内外同时同时显示隐藏" show-icon /> |
7 | + <a-button type="primary" class="my-4" @click="openDrawer2">打开Drawer</a-button> | ||
8 | + <Alert message="自适应高度/显示footer" show-icon /> | ||
9 | + <a-button type="primary" class="my-4" @click="openDrawer3">打开Drawer</a-button> | ||
10 | 10 | ||
11 | <Alert | 11 | <Alert |
12 | message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" | 12 | message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" |
13 | show-icon | 13 | show-icon |
14 | - class="my-4" | ||
15 | /> | 14 | /> |
16 | - <a-button type="primary" class="mr-2" @click="send">打开Drawer并传递数据</a-button> | ||
17 | - <Alert message="详情页模式" show-icon class="my-4" /> | ||
18 | - <a-button type="primary" class="mr-2" @click="openDrawer5">打开详情Drawer</a-button> | 15 | + <a-button type="primary" class="my-4" @click="send">打开Drawer并传递数据</a-button> |
16 | + <Alert message="详情页模式" show-icon /> | ||
17 | + <a-button type="primary" class="my-4" @click="openDrawer5">打开详情Drawer</a-button> | ||
19 | <Drawer1 @register="register1" /> | 18 | <Drawer1 @register="register1" /> |
20 | <Drawer2 @register="register2" /> | 19 | <Drawer2 @register="register2" /> |
21 | <Drawer3 @register="register3" /> | 20 | <Drawer3 @register="register3" /> |
src/views/demo/comp/modal/index.vue
1 | <template> | 1 | <template> |
2 | - <div class="px-10"> | 2 | + <div class="px-10 py-4"> |
3 | <Alert | 3 | <Alert |
4 | message="使用 useModal 进行弹窗操作,默认可以拖动,可以通过 draggable | 4 | message="使用 useModal 进行弹窗操作,默认可以拖动,可以通过 draggable |
5 | 参数进行控制是否可以拖动/全屏" | 5 | 参数进行控制是否可以拖动/全屏" |
6 | show-icon | 6 | show-icon |
7 | - class="my-4" | ||
8 | /> | 7 | /> |
9 | - <a-button type="primary" class="mr-2" @click="openModalLoading" | 8 | + <a-button type="primary" class="my-4" @click="openModalLoading" |
10 | >打开弹窗 默认可以拖动/全屏</a-button | 9 | >打开弹窗 默认可以拖动/全屏</a-button |
11 | > | 10 | > |
12 | 11 | ||
13 | - <Alert message="内外同时同时显示隐藏" show-icon class="my-4" /> | ||
14 | - <a-button type="primary" class="mr-2" @click="openModal2">打开弹窗</a-button> | ||
15 | - <Alert message="自适应高度" show-icon class="my-4" /> | ||
16 | - <a-button type="primary" class="mr-2" @click="openModal3">打开弹窗</a-button> | 12 | + <Alert message="内外同时同时显示隐藏" show-icon /> |
13 | + <a-button type="primary" class="my-4" @click="openModal2">打开弹窗</a-button> | ||
14 | + <Alert message="自适应高度" show-icon /> | ||
15 | + <a-button type="primary" class="my-4" @click="openModal3">打开弹窗</a-button> | ||
17 | 16 | ||
18 | <Alert | 17 | <Alert |
19 | message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" | 18 | message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" |
20 | show-icon | 19 | show-icon |
21 | - class="my-4" | ||
22 | /> | 20 | /> |
23 | - <a-button type="primary" class="mr-2" @click="send">打开弹窗并传递数据</a-button> | 21 | + <a-button type="primary" class="my-4" @click="send">打开弹窗并传递数据</a-button> |
24 | 22 | ||
25 | <Modal1 @register="register1" /> | 23 | <Modal1 @register="register1" /> |
26 | <Modal2 @register="register2" /> | 24 | <Modal2 @register="register2" /> |