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 | 5 | - 表单组件现在支持直接传入 model 直接进行 set 操作,参考**组件->弹窗扩展->打开弹窗并传递数据** |
6 | 6 | |
7 | 7 | - modal 的 useModalInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值, |
8 | + | |
8 | 9 | - 用于处理打开弹窗对表单等组件的设置值。参考**组件->弹窗扩展->打开弹窗并传递数据** |
9 | 10 | - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。 |
10 | 11 | |
12 | +- drawer 的 useDrawerInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值, | |
13 | + - 用于处理打开抽屉对表单等组件的设置值。参考**组件->抽屉扩展->打开抽屉并传递数据** | |
14 | + - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。 | |
15 | + | |
11 | 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 | 3 | import { defineComponent, ref, computed, watchEffect, watch, unref, nextTick, toRaw } from 'vue'; |
4 | +import { Drawer, Row, Col, Button } from 'ant-design-vue'; | |
5 | + | |
3 | 6 | import { BasicTitle } from '/@/components/Basic'; |
4 | 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 | 10 | import { basicProps } from './props'; |
11 | + | |
12 | +import { getSlot } from '/@/utils/helper/tsxHelper'; | |
11 | 13 | import { isFunction, isNumber } from '/@/utils/is'; |
12 | -import { LeftOutlined } from '@ant-design/icons-vue'; | |
13 | 14 | import { buildUUID } from '/@/utils/uuid'; |
14 | 15 | import { deepMerge } from '/@/utils'; |
16 | + | |
15 | 17 | import './index.less'; |
16 | 18 | |
17 | 19 | const prefixCls = 'basic-drawer'; |
... | ... | @@ -31,7 +33,6 @@ export default defineComponent({ |
31 | 33 | |
32 | 34 | const getProps = computed(() => { |
33 | 35 | const opt: any = { |
34 | - // @ts-ignore | |
35 | 36 | placement: 'right', |
36 | 37 | ...attrs, |
37 | 38 | ...props, |
... | ... | @@ -47,7 +48,6 @@ export default defineComponent({ |
47 | 48 | opt.wrapClassName = opt.wrapClassName |
48 | 49 | ? `${opt.wrapClassName} ${prefixCls}__detail` |
49 | 50 | : `${prefixCls}__detail`; |
50 | - // opt.maskClosable = false; | |
51 | 51 | if (!opt.getContainer) { |
52 | 52 | opt.getContainer = `.default-layout__main`; |
53 | 53 | } |
... | ... | @@ -128,11 +128,11 @@ export default defineComponent({ |
128 | 128 | {showOkBtn && ( |
129 | 129 | <Button |
130 | 130 | type={okType} |
131 | - {...okButtonProps} | |
132 | - loading={confirmLoading} | |
133 | 131 | onClick={() => { |
134 | 132 | emit('ok'); |
135 | 133 | }} |
134 | + {...okButtonProps} | |
135 | + loading={confirmLoading} | |
136 | 136 | > |
137 | 137 | {() => okText} |
138 | 138 | </Button> |
... | ... | @@ -152,13 +152,9 @@ export default defineComponent({ |
152 | 152 | {() => ( |
153 | 153 | <> |
154 | 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 | 160 | {title && ( | ... | ... |
src/components/Drawer/src/types.ts
... | ... | @@ -5,10 +5,12 @@ import type { ScrollContainerOptions } from '/@/components/Container/index'; |
5 | 5 | export interface DrawerInstance { |
6 | 6 | setDrawerProps: (props: Partial<DrawerProps> | boolean) => void; |
7 | 7 | } |
8 | + | |
8 | 9 | export interface ReturnMethods extends DrawerInstance { |
9 | 10 | openDrawer: (visible?: boolean) => void; |
10 | 11 | transferDrawerData: (data: any) => void; |
11 | 12 | } |
13 | + | |
12 | 14 | export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void; |
13 | 15 | |
14 | 16 | export interface ReturnInnerMethods extends DrawerInstance { |
... | ... | @@ -19,6 +21,7 @@ export interface ReturnInnerMethods extends DrawerInstance { |
19 | 21 | } |
20 | 22 | |
21 | 23 | export type UseDrawerReturnType = [RegisterFn, ReturnMethods]; |
24 | + | |
22 | 25 | export type UseDrawerInnerReturnType = [RegisterFn, ReturnInnerMethods]; |
23 | 26 | |
24 | 27 | export interface DrawerFooterProps { | ... | ... |
src/components/Drawer/src/useDrawer.ts
... | ... | @@ -5,8 +5,11 @@ import type { |
5 | 5 | DrawerProps, |
6 | 6 | UseDrawerInnerReturnType, |
7 | 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 | 11 | import { isProdMode } from '/@/utils/env'; |
12 | +import { isFunction } from '/@/utils/is'; | |
10 | 13 | |
11 | 14 | const dataTransferRef = reactive<any>({}); |
12 | 15 | /** |
... | ... | @@ -34,6 +37,7 @@ export function useDrawer(): UseDrawerReturnType { |
34 | 37 | drawerRef.value = drawerInstance; |
35 | 38 | loadedRef.value = true; |
36 | 39 | } |
40 | + | |
37 | 41 | const getInstance = () => { |
38 | 42 | const instance = unref(drawerRef); |
39 | 43 | if (!instance) { |
... | ... | @@ -41,15 +45,18 @@ export function useDrawer(): UseDrawerReturnType { |
41 | 45 | } |
42 | 46 | return instance; |
43 | 47 | }; |
48 | + | |
44 | 49 | const methods: ReturnMethods = { |
45 | 50 | setDrawerProps: (props: Partial<DrawerProps>): void => { |
46 | 51 | getInstance().setDrawerProps(props); |
47 | 52 | }, |
53 | + | |
48 | 54 | openDrawer: (visible = true): void => { |
49 | 55 | getInstance().setDrawerProps({ |
50 | 56 | visible: visible, |
51 | 57 | }); |
52 | 58 | }, |
59 | + | |
53 | 60 | transferDrawerData(val: any) { |
54 | 61 | dataTransferRef[unref(uidRef)] = val; |
55 | 62 | }, |
... | ... | @@ -57,7 +64,7 @@ export function useDrawer(): UseDrawerReturnType { |
57 | 64 | |
58 | 65 | return [getDrawer, methods]; |
59 | 66 | } |
60 | -export const useDrawerInner = (): UseDrawerInnerReturnType => { | |
67 | +export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => { | |
61 | 68 | const drawerInstanceRef = ref<DrawerInstance | null>(null); |
62 | 69 | const currentInstall = getCurrentInstance(); |
63 | 70 | const uidRef = ref<string>(''); |
... | ... | @@ -65,6 +72,7 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => { |
65 | 72 | if (!currentInstall) { |
66 | 73 | throw new Error('instance is undefined!'); |
67 | 74 | } |
75 | + | |
68 | 76 | const getInstance = () => { |
69 | 77 | const instance = unref(drawerInstanceRef); |
70 | 78 | if (!instance) { |
... | ... | @@ -72,26 +80,39 @@ export const useDrawerInner = (): UseDrawerInnerReturnType => { |
72 | 80 | } |
73 | 81 | return instance; |
74 | 82 | }; |
83 | + | |
75 | 84 | const register = (modalInstance: DrawerInstance, uuid: string) => { |
76 | 85 | uidRef.value = uuid; |
77 | 86 | drawerInstanceRef.value = modalInstance; |
78 | 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 | 97 | return [ |
81 | 98 | register, |
82 | 99 | { |
83 | 100 | receiveDrawerDataRef: computed(() => { |
84 | 101 | return dataTransferRef[unref(uidRef)]; |
85 | 102 | }), |
103 | + | |
86 | 104 | changeLoading: (loading = true) => { |
87 | 105 | getInstance().setDrawerProps({ loading }); |
88 | 106 | }, |
107 | + | |
89 | 108 | changeOkLoading: (loading = true) => { |
90 | 109 | getInstance().setDrawerProps({ confirmLoading: loading }); |
91 | 110 | }, |
111 | + | |
92 | 112 | closeDrawer: () => { |
93 | 113 | getInstance().setDrawerProps({ visible: false }); |
94 | 114 | }, |
115 | + | |
95 | 116 | setDrawerProps: (props: Partial<DrawerProps>) => { |
96 | 117 | getInstance().setDrawerProps(props); |
97 | 118 | }, | ... | ... |
src/views/demo/comp/drawer/Drawer4.vue
1 | 1 | <template> |
2 | 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 | 7 | </BasicDrawer> |
5 | 8 | </template> |
6 | 9 | <script lang="ts"> |
7 | - import { defineComponent } from 'vue'; | |
10 | + import { defineComponent, nextTick } from 'vue'; | |
8 | 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 | 33 | export default defineComponent({ |
10 | - components: { BasicDrawer }, | |
34 | + components: { BasicDrawer, BasicForm }, | |
11 | 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 | 56 | </script> | ... | ... |
src/views/demo/comp/drawer/index.vue
1 | 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 | 11 | <Alert |
12 | 12 | message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" |
13 | 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 | 18 | <Drawer1 @register="register1" /> |
20 | 19 | <Drawer2 @register="register2" /> |
21 | 20 | <Drawer3 @register="register3" /> | ... | ... |
src/views/demo/comp/modal/index.vue
1 | 1 | <template> |
2 | - <div class="px-10"> | |
2 | + <div class="px-10 py-4"> | |
3 | 3 | <Alert |
4 | 4 | message="使用 useModal 进行弹窗操作,默认可以拖动,可以通过 draggable |
5 | 5 | 参数进行控制是否可以拖动/全屏" |
6 | 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 | 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 | 17 | <Alert |
19 | 18 | message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" |
20 | 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 | 23 | <Modal1 @register="register1" /> |
26 | 24 | <Modal2 @register="register2" /> | ... | ... |