Commit 1c1755cf5b4ada7263c05ddf4105abb52a2abb2f
1 parent
639520ad
fix(modal): ensure that the full screen height is calculated correctly
Showing
25 changed files
with
116 additions
and
118 deletions
CHANGELOG.zh_CN.md
@@ -2,9 +2,15 @@ | @@ -2,9 +2,15 @@ | ||
2 | 2 | ||
3 | ### ✨ Features | 3 | ### ✨ Features |
4 | 4 | ||
5 | -- `Cropper` 头像裁剪新增圆形裁剪功能 | ||
6 | -- 新增头像上传组件 | ||
7 | -- `useDrawer`新增`closeDrawer`函数 | 5 | +- **CropperImage** `Cropper` 头像裁剪新增圆形裁剪功能 |
6 | +- **CropperAvatar** 新增头像上传组件 | ||
7 | +- **Drawer** `useDrawer`新增`closeDrawer`函数 | ||
8 | + | ||
9 | +### 🐛 Bug Fixes | ||
10 | + | ||
11 | +- **Modal** 修复全屏高度计算错误 | ||
12 | +- **PageWrapper** 修复高度计算问题 | ||
13 | +- 修复后台模式下,Iframe 路由错误 | ||
8 | 14 | ||
9 | ## 2.4.2(2021-06-10) | 15 | ## 2.4.2(2021-06-10) |
10 | 16 |
src/components/Drawer/src/BasicDrawer.vue
@@ -163,7 +163,7 @@ | @@ -163,7 +163,7 @@ | ||
163 | 163 | ||
164 | function setDrawerProps(props: Partial<DrawerProps>): void { | 164 | function setDrawerProps(props: Partial<DrawerProps>): void { |
165 | // Keep the last setDrawerProps | 165 | // Keep the last setDrawerProps |
166 | - propsRef.value = deepMerge((unref(propsRef) as any) || {}, props); | 166 | + propsRef.value = deepMerge(unref(propsRef), props); |
167 | 167 | ||
168 | if (Reflect.has(props, 'visible')) { | 168 | if (Reflect.has(props, 'visible')) { |
169 | visibleRef.value = !!props.visible; | 169 | visibleRef.value = !!props.visible; |
src/components/Drawer/src/useDrawer.ts
@@ -5,7 +5,6 @@ import type { | @@ -5,7 +5,6 @@ import type { | ||
5 | DrawerProps, | 5 | DrawerProps, |
6 | UseDrawerInnerReturnType, | 6 | UseDrawerInnerReturnType, |
7 | } from './typing'; | 7 | } from './typing'; |
8 | - | ||
9 | import { | 8 | import { |
10 | ref, | 9 | ref, |
11 | getCurrentInstance, | 10 | getCurrentInstance, |
@@ -16,11 +15,9 @@ import { | @@ -16,11 +15,9 @@ import { | ||
16 | toRaw, | 15 | toRaw, |
17 | computed, | 16 | computed, |
18 | } from 'vue'; | 17 | } from 'vue'; |
19 | - | ||
20 | import { isProdMode } from '/@/utils/env'; | 18 | import { isProdMode } from '/@/utils/env'; |
21 | import { isFunction } from '/@/utils/is'; | 19 | import { isFunction } from '/@/utils/is'; |
22 | import { tryOnUnmounted } from '@vueuse/core'; | 20 | import { tryOnUnmounted } from '@vueuse/core'; |
23 | - | ||
24 | import { isEqual } from 'lodash-es'; | 21 | import { isEqual } from 'lodash-es'; |
25 | import { error } from '/@/utils/log'; | 22 | import { error } from '/@/utils/log'; |
26 | 23 |
src/components/Modal/index.ts
1 | +import { withInstall } from '/@/utils'; | ||
1 | import './src/index.less'; | 2 | import './src/index.less'; |
2 | -import BasicModal from './src/BasicModal.vue'; | 3 | +import basicModal from './src/BasicModal.vue'; |
3 | 4 | ||
4 | -export { BasicModal }; | 5 | +export const BasicModal = withInstall(basicModal); |
5 | export { useModalContext } from './src/hooks/useModalContext'; | 6 | export { useModalContext } from './src/hooks/useModalContext'; |
6 | export { useModal, useModalInner } from './src/hooks/useModal'; | 7 | export { useModal, useModalInner } from './src/hooks/useModal'; |
7 | -export * from './src/types'; | 8 | +export * from './src/typing'; |
src/components/Modal/src/BasicModal.vue
@@ -49,7 +49,7 @@ | @@ -49,7 +49,7 @@ | ||
49 | </Modal> | 49 | </Modal> |
50 | </template> | 50 | </template> |
51 | <script lang="ts"> | 51 | <script lang="ts"> |
52 | - import type { ModalProps, ModalMethods } from './types'; | 52 | + import type { ModalProps, ModalMethods } from './typing'; |
53 | 53 | ||
54 | import { | 54 | import { |
55 | defineComponent, | 55 | defineComponent, |
@@ -62,20 +62,17 @@ | @@ -62,20 +62,17 @@ | ||
62 | getCurrentInstance, | 62 | getCurrentInstance, |
63 | nextTick, | 63 | nextTick, |
64 | } from 'vue'; | 64 | } from 'vue'; |
65 | - | ||
66 | import Modal from './components/Modal'; | 65 | import Modal from './components/Modal'; |
67 | import ModalWrapper from './components/ModalWrapper.vue'; | 66 | import ModalWrapper from './components/ModalWrapper.vue'; |
68 | import ModalClose from './components/ModalClose.vue'; | 67 | import ModalClose from './components/ModalClose.vue'; |
69 | import ModalFooter from './components/ModalFooter.vue'; | 68 | import ModalFooter from './components/ModalFooter.vue'; |
70 | import ModalHeader from './components/ModalHeader.vue'; | 69 | import ModalHeader from './components/ModalHeader.vue'; |
71 | - | ||
72 | import { isFunction } from '/@/utils/is'; | 70 | import { isFunction } from '/@/utils/is'; |
73 | import { deepMerge } from '/@/utils'; | 71 | import { deepMerge } from '/@/utils'; |
74 | - | ||
75 | import { basicProps } from './props'; | 72 | import { basicProps } from './props'; |
76 | import { useFullScreen } from './hooks/useModalFullScreen'; | 73 | import { useFullScreen } from './hooks/useModalFullScreen'; |
77 | - | ||
78 | import { omit } from 'lodash-es'; | 74 | import { omit } from 'lodash-es'; |
75 | + | ||
79 | export default defineComponent({ | 76 | export default defineComponent({ |
80 | name: 'BasicModal', | 77 | name: 'BasicModal', |
81 | components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader }, | 78 | components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader }, |
@@ -189,7 +186,7 @@ | @@ -189,7 +186,7 @@ | ||
189 | */ | 186 | */ |
190 | function setModalProps(props: Partial<ModalProps>): void { | 187 | function setModalProps(props: Partial<ModalProps>): void { |
191 | // Keep the last setModalProps | 188 | // Keep the last setModalProps |
192 | - propsRef.value = deepMerge(unref(propsRef) || {}, props); | 189 | + propsRef.value = deepMerge(unref(propsRef), props); |
193 | if (!Reflect.has(props, 'visible')) return; | 190 | if (!Reflect.has(props, 'visible')) return; |
194 | visibleRef.value = !!props.visible; | 191 | visibleRef.value = !!props.visible; |
195 | } | 192 | } |
src/components/Modal/src/components/Modal.tsx
@@ -20,7 +20,6 @@ export default defineComponent({ | @@ -20,7 +20,6 @@ export default defineComponent({ | ||
20 | 20 | ||
21 | return () => { | 21 | return () => { |
22 | const propsData = { ...unref(attrs), ...props } as Recordable; | 22 | const propsData = { ...unref(attrs), ...props } as Recordable; |
23 | - | ||
24 | return <Modal {...propsData}>{extendSlots(slots)}</Modal>; | 23 | return <Modal {...propsData}>{extendSlots(slots)}</Modal>; |
25 | }; | 24 | }; |
26 | }, | 25 | }, |
src/components/Modal/src/components/ModalClose.vue
@@ -2,7 +2,6 @@ | @@ -2,7 +2,6 @@ | ||
2 | <div :class="getClass"> | 2 | <div :class="getClass"> |
3 | <template v-if="canFullscreen"> | 3 | <template v-if="canFullscreen"> |
4 | <FullscreenExitOutlined role="full" @click="handleFullScreen" v-if="fullScreen" /> | 4 | <FullscreenExitOutlined role="full" @click="handleFullScreen" v-if="fullScreen" /> |
5 | - | ||
6 | <FullscreenOutlined role="close" @click="handleFullScreen" v-else /> | 5 | <FullscreenOutlined role="close" @click="handleFullScreen" v-else /> |
7 | </template> | 6 | </template> |
8 | <CloseOutlined @click="handleCancel" /> | 7 | <CloseOutlined @click="handleCancel" /> |
@@ -12,14 +11,13 @@ | @@ -12,14 +11,13 @@ | ||
12 | import { defineComponent, computed } from 'vue'; | 11 | import { defineComponent, computed } from 'vue'; |
13 | import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue'; | 12 | import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue'; |
14 | import { useDesign } from '/@/hooks/web/useDesign'; | 13 | import { useDesign } from '/@/hooks/web/useDesign'; |
15 | - import { propTypes } from '/@/utils/propTypes'; | ||
16 | 14 | ||
17 | export default defineComponent({ | 15 | export default defineComponent({ |
18 | name: 'ModalClose', | 16 | name: 'ModalClose', |
19 | components: { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined }, | 17 | components: { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined }, |
20 | props: { | 18 | props: { |
21 | - canFullscreen: propTypes.bool.def(true), | ||
22 | - fullScreen: propTypes.bool, | 19 | + canFullscreen: { type: Boolean, default: true }, |
20 | + fullScreen: { type: Boolean }, | ||
23 | }, | 21 | }, |
24 | emits: ['cancel', 'fullscreen'], | 22 | emits: ['cancel', 'fullscreen'], |
25 | setup(props, { emit }) { | 23 | setup(props, { emit }) { |
@@ -38,6 +36,7 @@ | @@ -38,6 +36,7 @@ | ||
38 | function handleCancel(e: Event) { | 36 | function handleCancel(e: Event) { |
39 | emit('cancel', e); | 37 | emit('cancel', e); |
40 | } | 38 | } |
39 | + | ||
41 | function handleFullScreen(e: Event) { | 40 | function handleFullScreen(e: Event) { |
42 | e?.stopPropagation(); | 41 | e?.stopPropagation(); |
43 | e?.preventDefault(); | 42 | e?.preventDefault(); |
src/components/Modal/src/components/ModalFooter.vue
src/components/Modal/src/components/ModalHeader.vue
@@ -8,7 +8,6 @@ | @@ -8,7 +8,6 @@ | ||
8 | import { defineComponent } from 'vue'; | 8 | import { defineComponent } from 'vue'; |
9 | import { BasicTitle } from '/@/components/Basic'; | 9 | import { BasicTitle } from '/@/components/Basic'; |
10 | 10 | ||
11 | - import { propTypes } from '/@/utils/propTypes'; | ||
12 | export default defineComponent({ | 11 | export default defineComponent({ |
13 | name: 'BasicModalHeader', | 12 | name: 'BasicModalHeader', |
14 | components: { BasicTitle }, | 13 | components: { BasicTitle }, |
@@ -16,7 +15,7 @@ | @@ -16,7 +15,7 @@ | ||
16 | helpMessage: { | 15 | helpMessage: { |
17 | type: [String, Array] as PropType<string | string[]>, | 16 | type: [String, Array] as PropType<string | string[]>, |
18 | }, | 17 | }, |
19 | - title: propTypes.string, | 18 | + title: { type: String }, |
20 | }, | 19 | }, |
21 | }); | 20 | }); |
22 | </script> | 21 | </script> |
src/components/Modal/src/components/ModalWrapper.vue
@@ -6,9 +6,7 @@ | @@ -6,9 +6,7 @@ | ||
6 | </ScrollContainer> | 6 | </ScrollContainer> |
7 | </template> | 7 | </template> |
8 | <script lang="ts"> | 8 | <script lang="ts"> |
9 | - import type { ModalWrapperProps } from '../types'; | ||
10 | import type { CSSProperties } from 'vue'; | 9 | import type { CSSProperties } from 'vue'; |
11 | - | ||
12 | import { | 10 | import { |
13 | defineComponent, | 11 | defineComponent, |
14 | computed, | 12 | computed, |
@@ -20,31 +18,31 @@ | @@ -20,31 +18,31 @@ | ||
20 | nextTick, | 18 | nextTick, |
21 | onUnmounted, | 19 | onUnmounted, |
22 | } from 'vue'; | 20 | } from 'vue'; |
23 | - | ||
24 | import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; | 21 | import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; |
25 | import { ScrollContainer } from '/@/components/Container'; | 22 | import { ScrollContainer } from '/@/components/Container'; |
26 | - | ||
27 | - import { propTypes } from '/@/utils/propTypes'; | ||
28 | import { createModalContext } from '../hooks/useModalContext'; | 23 | import { createModalContext } from '../hooks/useModalContext'; |
24 | + import { useMutationObserver } from '@vueuse/core'; | ||
25 | + | ||
26 | + const props = { | ||
27 | + loading: { type: Boolean }, | ||
28 | + useWrapper: { type: Boolean, default: true }, | ||
29 | + modalHeaderHeight: { type: Number, default: 57 }, | ||
30 | + modalFooterHeight: { type: Number, default: 74 }, | ||
31 | + minHeight: { type: Number, default: 200 }, | ||
32 | + height: { type: Number }, | ||
33 | + footerOffset: { type: Number, default: 0 }, | ||
34 | + visible: { type: Boolean }, | ||
35 | + fullScreen: { type: Boolean }, | ||
36 | + loadingTip: { type: String }, | ||
37 | + }; | ||
29 | 38 | ||
30 | export default defineComponent({ | 39 | export default defineComponent({ |
31 | name: 'ModalWrapper', | 40 | name: 'ModalWrapper', |
32 | components: { ScrollContainer }, | 41 | components: { ScrollContainer }, |
33 | inheritAttrs: false, | 42 | inheritAttrs: false, |
34 | - props: { | ||
35 | - loading: propTypes.bool, | ||
36 | - useWrapper: propTypes.bool.def(true), | ||
37 | - modalHeaderHeight: propTypes.number.def(57), | ||
38 | - modalFooterHeight: propTypes.number.def(74), | ||
39 | - minHeight: propTypes.number.def(200), | ||
40 | - height: propTypes.number, | ||
41 | - footerOffset: propTypes.number.def(0), | ||
42 | - visible: propTypes.bool, | ||
43 | - fullScreen: propTypes.bool, | ||
44 | - loadingTip: propTypes.string, | ||
45 | - }, | 43 | + props, |
46 | emits: ['height-change', 'ext-height'], | 44 | emits: ['height-change', 'ext-height'], |
47 | - setup(props: ModalWrapperProps, { emit }) { | 45 | + setup(props, { emit }) { |
48 | const wrapperRef = ref<ComponentRef>(null); | 46 | const wrapperRef = ref<ComponentRef>(null); |
49 | const spinRef = ref<ElRef>(null); | 47 | const spinRef = ref<ElRef>(null); |
50 | const realHeightRef = ref(0); | 48 | const realHeightRef = ref(0); |
@@ -56,6 +54,17 @@ | @@ -56,6 +54,17 @@ | ||
56 | 54 | ||
57 | useWindowSizeFn(setModalHeight.bind(null, false)); | 55 | useWindowSizeFn(setModalHeight.bind(null, false)); |
58 | 56 | ||
57 | + useMutationObserver( | ||
58 | + spinRef, | ||
59 | + () => { | ||
60 | + setModalHeight(); | ||
61 | + }, | ||
62 | + { | ||
63 | + attributes: true, | ||
64 | + subtree: true, | ||
65 | + } | ||
66 | + ); | ||
67 | + | ||
59 | createModalContext({ | 68 | createModalContext({ |
60 | redoModalHeight: setModalHeight, | 69 | redoModalHeight: setModalHeight, |
61 | }); | 70 | }); |
@@ -63,8 +72,7 @@ | @@ -63,8 +72,7 @@ | ||
63 | const spinStyle = computed((): CSSProperties => { | 72 | const spinStyle = computed((): CSSProperties => { |
64 | return { | 73 | return { |
65 | minHeight: `${props.minHeight}px`, | 74 | minHeight: `${props.minHeight}px`, |
66 | - // padding 28 | ||
67 | - maxHeight: `${unref(realHeightRef)}px`, | 75 | + [props.fullScreen ? 'height' : 'maxHeight']: `${unref(realHeightRef)}px`, |
68 | }; | 76 | }; |
69 | }); | 77 | }); |
70 | 78 | ||
@@ -87,7 +95,6 @@ | @@ -87,7 +95,6 @@ | ||
87 | onMounted(() => { | 95 | onMounted(() => { |
88 | const { modalHeaderHeight, modalFooterHeight } = props; | 96 | const { modalHeaderHeight, modalFooterHeight } = props; |
89 | emit('ext-height', modalHeaderHeight + modalFooterHeight); | 97 | emit('ext-height', modalHeaderHeight + modalFooterHeight); |
90 | - // listenElResize(); | ||
91 | }); | 98 | }); |
92 | 99 | ||
93 | onUnmounted(() => { | 100 | onUnmounted(() => { |
src/components/Modal/src/hooks/useModal.ts
@@ -4,8 +4,7 @@ import type { | @@ -4,8 +4,7 @@ import type { | ||
4 | ModalProps, | 4 | ModalProps, |
5 | ReturnMethods, | 5 | ReturnMethods, |
6 | UseModalInnerReturnType, | 6 | UseModalInnerReturnType, |
7 | -} from '../types'; | ||
8 | - | 7 | +} from '../typing'; |
9 | import { | 8 | import { |
10 | ref, | 9 | ref, |
11 | onUnmounted, | 10 | onUnmounted, |
@@ -20,10 +19,10 @@ import { isProdMode } from '/@/utils/env'; | @@ -20,10 +19,10 @@ import { isProdMode } from '/@/utils/env'; | ||
20 | import { isFunction } from '/@/utils/is'; | 19 | import { isFunction } from '/@/utils/is'; |
21 | import { isEqual } from 'lodash-es'; | 20 | import { isEqual } from 'lodash-es'; |
22 | import { tryOnUnmounted } from '@vueuse/core'; | 21 | import { tryOnUnmounted } from '@vueuse/core'; |
23 | - | ||
24 | import { error } from '/@/utils/log'; | 22 | import { error } from '/@/utils/log'; |
25 | import { computed } from 'vue'; | 23 | import { computed } from 'vue'; |
26 | -const dataTransferRef = reactive<any>({}); | 24 | + |
25 | +const dataTransfer = reactive<any>({}); | ||
27 | 26 | ||
28 | const visibleData = reactive<{ [key: number]: boolean }>({}); | 27 | const visibleData = reactive<{ [key: number]: boolean }>({}); |
29 | 28 | ||
@@ -31,29 +30,31 @@ const visibleData = reactive<{ [key: number]: boolean }>({}); | @@ -31,29 +30,31 @@ const visibleData = reactive<{ [key: number]: boolean }>({}); | ||
31 | * @description: Applicable to independent modal and call outside | 30 | * @description: Applicable to independent modal and call outside |
32 | */ | 31 | */ |
33 | export function useModal(): UseModalReturnType { | 32 | export function useModal(): UseModalReturnType { |
34 | - const modalRef = ref<Nullable<ModalMethods>>(null); | ||
35 | - const loadedRef = ref<Nullable<boolean>>(false); | ||
36 | - const uidRef = ref<string>(''); | 33 | + const modal = ref<Nullable<ModalMethods>>(null); |
34 | + const loaded = ref<Nullable<boolean>>(false); | ||
35 | + const uid = ref<string>(''); | ||
37 | 36 | ||
38 | function register(modalMethod: ModalMethods, uuid: string) { | 37 | function register(modalMethod: ModalMethods, uuid: string) { |
39 | - uidRef.value = uuid; | ||
40 | - | 38 | + if (!getCurrentInstance()) { |
39 | + throw new Error('useModal() can only be used inside setup() or functional components!'); | ||
40 | + } | ||
41 | + uid.value = uuid; | ||
41 | isProdMode() && | 42 | isProdMode() && |
42 | onUnmounted(() => { | 43 | onUnmounted(() => { |
43 | - modalRef.value = null; | ||
44 | - loadedRef.value = false; | ||
45 | - dataTransferRef[unref(uidRef)] = null; | 44 | + modal.value = null; |
45 | + loaded.value = false; | ||
46 | + dataTransfer[unref(uid)] = null; | ||
46 | }); | 47 | }); |
47 | - if (unref(loadedRef) && isProdMode() && modalMethod === unref(modalRef)) return; | 48 | + if (unref(loaded) && isProdMode() && modalMethod === unref(modal)) return; |
48 | 49 | ||
49 | - modalRef.value = modalMethod; | 50 | + modal.value = modalMethod; |
50 | modalMethod.emitVisible = (visible: boolean, uid: number) => { | 51 | modalMethod.emitVisible = (visible: boolean, uid: number) => { |
51 | visibleData[uid] = visible; | 52 | visibleData[uid] = visible; |
52 | }; | 53 | }; |
53 | } | 54 | } |
54 | 55 | ||
55 | const getInstance = () => { | 56 | const getInstance = () => { |
56 | - const instance = unref(modalRef); | 57 | + const instance = unref(modal); |
57 | if (!instance) { | 58 | if (!instance) { |
58 | error('useModal instance is undefined!'); | 59 | error('useModal instance is undefined!'); |
59 | } | 60 | } |
@@ -66,7 +67,7 @@ export function useModal(): UseModalReturnType { | @@ -66,7 +67,7 @@ export function useModal(): UseModalReturnType { | ||
66 | }, | 67 | }, |
67 | 68 | ||
68 | getVisible: computed((): boolean => { | 69 | getVisible: computed((): boolean => { |
69 | - return visibleData[~~unref(uidRef)]; | 70 | + return visibleData[~~unref(uid)]; |
70 | }), | 71 | }), |
71 | 72 | ||
72 | redoModalHeight: () => { | 73 | redoModalHeight: () => { |
@@ -79,15 +80,15 @@ export function useModal(): UseModalReturnType { | @@ -79,15 +80,15 @@ export function useModal(): UseModalReturnType { | ||
79 | }); | 80 | }); |
80 | 81 | ||
81 | if (!data) return; | 82 | if (!data) return; |
82 | - | 83 | + const id = unref(uid); |
83 | if (openOnSet) { | 84 | if (openOnSet) { |
84 | - dataTransferRef[unref(uidRef)] = null; | ||
85 | - dataTransferRef[unref(uidRef)] = toRaw(data); | 85 | + dataTransfer[id] = null; |
86 | + dataTransfer[id] = toRaw(data); | ||
86 | return; | 87 | return; |
87 | } | 88 | } |
88 | - const equal = isEqual(toRaw(dataTransferRef[unref(uidRef)]), toRaw(data)); | 89 | + const equal = isEqual(toRaw(dataTransfer[id]), toRaw(data)); |
89 | if (!equal) { | 90 | if (!equal) { |
90 | - dataTransferRef[unref(uidRef)] = toRaw(data); | 91 | + dataTransfer[id] = toRaw(data); |
91 | } | 92 | } |
92 | }, | 93 | }, |
93 | 94 | ||
@@ -103,9 +104,6 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => { | @@ -103,9 +104,6 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => { | ||
103 | const currentInstance = getCurrentInstance(); | 104 | const currentInstance = getCurrentInstance(); |
104 | const uidRef = ref<string>(''); | 105 | const uidRef = ref<string>(''); |
105 | 106 | ||
106 | - // currentInstall.type.emits = [...currentInstall.type.emits, 'register']; | ||
107 | - // Object.assign(currentInstall.type.emits, ['register']); | ||
108 | - | ||
109 | const getInstance = () => { | 107 | const getInstance = () => { |
110 | const instance = unref(modalInstanceRef); | 108 | const instance = unref(modalInstanceRef); |
111 | if (!instance) { | 109 | if (!instance) { |
@@ -125,7 +123,7 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => { | @@ -125,7 +123,7 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => { | ||
125 | }; | 123 | }; |
126 | 124 | ||
127 | watchEffect(() => { | 125 | watchEffect(() => { |
128 | - const data = dataTransferRef[unref(uidRef)]; | 126 | + const data = dataTransfer[unref(uidRef)]; |
129 | if (!data) return; | 127 | if (!data) return; |
130 | if (!callbackFn || !isFunction(callbackFn)) return; | 128 | if (!callbackFn || !isFunction(callbackFn)) return; |
131 | nextTick(() => { | 129 | nextTick(() => { |
src/components/Modal/src/hooks/useModalFullScreen.ts
@@ -12,7 +12,6 @@ export function useFullScreen(context: UseFullScreenContext) { | @@ -12,7 +12,6 @@ export function useFullScreen(context: UseFullScreenContext) { | ||
12 | 12 | ||
13 | const getWrapClassName = computed(() => { | 13 | const getWrapClassName = computed(() => { |
14 | const clsName = unref(context.wrapClassName) || ''; | 14 | const clsName = unref(context.wrapClassName) || ''; |
15 | - | ||
16 | return unref(fullScreenRef) ? `fullscreen-modal ${clsName} ` : unref(clsName); | 15 | return unref(fullScreenRef) ? `fullscreen-modal ${clsName} ` : unref(clsName); |
17 | }); | 16 | }); |
18 | 17 |
src/components/Modal/src/props.ts
1 | import type { PropType, CSSProperties } from 'vue'; | 1 | import type { PropType, CSSProperties } from 'vue'; |
2 | +import type { ModalWrapperProps } from './typing'; | ||
2 | import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; | 3 | import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; |
3 | - | ||
4 | import { useI18n } from '/@/hooks/web/useI18n'; | 4 | import { useI18n } from '/@/hooks/web/useI18n'; |
5 | -import { propTypes, VueNode } from '/@/utils/propTypes'; | ||
6 | -import type { ModalWrapperProps } from './types'; | 5 | + |
7 | const { t } = useI18n(); | 6 | const { t } = useI18n(); |
8 | 7 | ||
9 | export const modalProps = { | 8 | export const modalProps = { |
10 | - visible: propTypes.bool, | ||
11 | - scrollTop: propTypes.bool.def(true), | ||
12 | - height: propTypes.number, | ||
13 | - minHeight: propTypes.number, | 9 | + visible: { type: Boolean }, |
10 | + scrollTop: { type: Boolean, default: true }, | ||
11 | + height: { type: Number }, | ||
12 | + minHeight: { type: Number }, | ||
14 | // open drag | 13 | // open drag |
15 | - draggable: propTypes.bool.def(true), | ||
16 | - centered: propTypes.bool, | ||
17 | - cancelText: propTypes.string.def(t('common.cancelText')), | ||
18 | - okText: propTypes.string.def(t('common.okText')), | 14 | + draggable: { type: Boolean, default: true }, |
15 | + centered: { type: Boolean }, | ||
16 | + cancelText: { type: String, default: t('common.cancelText') }, | ||
17 | + okText: { type: String, default: t('common.okText') }, | ||
19 | 18 | ||
20 | closeFunc: Function as PropType<() => Promise<boolean>>, | 19 | closeFunc: Function as PropType<() => Promise<boolean>>, |
21 | }; | 20 | }; |
22 | 21 | ||
23 | export const basicProps = Object.assign({}, modalProps, { | 22 | export const basicProps = Object.assign({}, modalProps, { |
24 | - defaultFullscreen: propTypes.bool, | 23 | + defaultFullscreen: { type: Boolean }, |
25 | // Can it be full screen | 24 | // Can it be full screen |
26 | - canFullscreen: propTypes.bool.def(true), | 25 | + canFullscreen: { type: Boolean, default: true }, |
27 | // After enabling the wrapper, the bottom can be increased in height | 26 | // After enabling the wrapper, the bottom can be increased in height |
28 | - wrapperFooterOffset: propTypes.number.def(0), | 27 | + wrapperFooterOffset: { type: Number, default: 0 }, |
29 | // Warm reminder message | 28 | // Warm reminder message |
30 | helpMessage: [String, Array] as PropType<string | string[]>, | 29 | helpMessage: [String, Array] as PropType<string | string[]>, |
31 | // Whether to setting wrapper | 30 | // Whether to setting wrapper |
32 | - useWrapper: propTypes.bool.def(true), | ||
33 | - loading: propTypes.bool, | ||
34 | - loadingTip: propTypes.string, | 31 | + useWrapper: { type: Boolean, default: true }, |
32 | + loading: { type: Boolean }, | ||
33 | + loadingTip: { type: String }, | ||
35 | /** | 34 | /** |
36 | * @description: Show close button | 35 | * @description: Show close button |
37 | */ | 36 | */ |
38 | - showCancelBtn: propTypes.bool.def(true), | 37 | + showCancelBtn: { type: Boolean, default: true }, |
39 | /** | 38 | /** |
40 | * @description: Show confirmation button | 39 | * @description: Show confirmation button |
41 | */ | 40 | */ |
42 | - showOkBtn: propTypes.bool.def(true), | 41 | + showOkBtn: { type: Boolean, default: true }, |
43 | 42 | ||
44 | wrapperProps: Object as PropType<Partial<ModalWrapperProps>>, | 43 | wrapperProps: Object as PropType<Partial<ModalWrapperProps>>, |
45 | 44 | ||
@@ -47,38 +46,38 @@ export const basicProps = Object.assign({}, modalProps, { | @@ -47,38 +46,38 @@ export const basicProps = Object.assign({}, modalProps, { | ||
47 | 46 | ||
48 | bodyStyle: Object as PropType<CSSProperties>, | 47 | bodyStyle: Object as PropType<CSSProperties>, |
49 | 48 | ||
50 | - closable: propTypes.bool.def(true), | 49 | + closable: { type: Boolean, default: true }, |
51 | 50 | ||
52 | closeIcon: Object as PropType<VueNode>, | 51 | closeIcon: Object as PropType<VueNode>, |
53 | 52 | ||
54 | - confirmLoading: propTypes.bool, | 53 | + confirmLoading: { type: Boolean }, |
55 | 54 | ||
56 | - destroyOnClose: propTypes.bool, | 55 | + destroyOnClose: { type: Boolean }, |
57 | 56 | ||
58 | footer: Object as PropType<VueNode>, | 57 | footer: Object as PropType<VueNode>, |
59 | 58 | ||
60 | getContainer: Function as PropType<() => any>, | 59 | getContainer: Function as PropType<() => any>, |
61 | 60 | ||
62 | - mask: propTypes.bool.def(true), | 61 | + mask: { type: Boolean, default: true }, |
63 | 62 | ||
64 | - maskClosable: propTypes.bool.def(true), | ||
65 | - keyboard: propTypes.bool.def(true), | 63 | + maskClosable: { type: Boolean, default: true }, |
64 | + keyboard: { type: Boolean, default: true }, | ||
66 | 65 | ||
67 | maskStyle: Object as PropType<CSSProperties>, | 66 | maskStyle: Object as PropType<CSSProperties>, |
68 | 67 | ||
69 | - okType: propTypes.string.def('primary'), | 68 | + okType: { type: String, default: 'primary' }, |
70 | 69 | ||
71 | okButtonProps: Object as PropType<ButtonProps>, | 70 | okButtonProps: Object as PropType<ButtonProps>, |
72 | 71 | ||
73 | cancelButtonProps: Object as PropType<ButtonProps>, | 72 | cancelButtonProps: Object as PropType<ButtonProps>, |
74 | 73 | ||
75 | - title: propTypes.string, | 74 | + title: { type: String }, |
76 | 75 | ||
77 | - visible: propTypes.bool, | 76 | + visible: { type: Boolean }, |
78 | 77 | ||
79 | width: [String, Number] as PropType<string | number>, | 78 | width: [String, Number] as PropType<string | number>, |
80 | 79 | ||
81 | - wrapClassName: propTypes.string, | 80 | + wrapClassName: { type: String }, |
82 | 81 | ||
83 | - zIndex: propTypes.number, | 82 | + zIndex: { type: Number }, |
84 | }); | 83 | }); |
src/components/Modal/src/types.ts renamed to src/components/Modal/src/typing.ts
src/components/Qrcode/index.ts
src/components/Qrcode/src/Qrcode.vue
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | import { toCanvas, QRCodeRenderersOptions, LogoType } from './qrcodePlus'; | 8 | import { toCanvas, QRCodeRenderersOptions, LogoType } from './qrcodePlus'; |
9 | import { toDataURL } from 'qrcode'; | 9 | import { toDataURL } from 'qrcode'; |
10 | import { downloadByUrl } from '/@/utils/file/download'; | 10 | import { downloadByUrl } from '/@/utils/file/download'; |
11 | - import { QrcodeDoneEventParams } from './types'; | 11 | + import { QrcodeDoneEventParams } from './typing'; |
12 | 12 | ||
13 | export default defineComponent({ | 13 | export default defineComponent({ |
14 | name: 'QrCode', | 14 | name: 'QrCode', |
src/components/Qrcode/src/drawCanvas.ts
1 | import { toCanvas } from 'qrcode'; | 1 | import { toCanvas } from 'qrcode'; |
2 | import type { QRCodeRenderersOptions } from 'qrcode'; | 2 | import type { QRCodeRenderersOptions } from 'qrcode'; |
3 | -import { RenderQrCodeParams, ContentType } from './types'; | 3 | +import { RenderQrCodeParams, ContentType } from './typing'; |
4 | export const renderQrCode = ({ canvas, content, width = 0, options = {} }: RenderQrCodeParams) => { | 4 | export const renderQrCode = ({ canvas, content, width = 0, options = {} }: RenderQrCodeParams) => { |
5 | // 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率 | 5 | // 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率 |
6 | options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content); | 6 | options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content); |
src/components/Qrcode/src/drawLogo.ts
1 | import { isString } from '/@/utils/is'; | 1 | import { isString } from '/@/utils/is'; |
2 | -import { RenderQrCodeParams, LogoType } from './types'; | 2 | +import { RenderQrCodeParams, LogoType } from './typing'; |
3 | export const drawLogo = ({ canvas, logo }: RenderQrCodeParams) => { | 3 | export const drawLogo = ({ canvas, logo }: RenderQrCodeParams) => { |
4 | if (!logo) { | 4 | if (!logo) { |
5 | return new Promise((resolve) => { | 5 | return new Promise((resolve) => { |
6 | resolve((canvas as HTMLCanvasElement).toDataURL()); | 6 | resolve((canvas as HTMLCanvasElement).toDataURL()); |
7 | }); | 7 | }); |
8 | } | 8 | } |
9 | - | ||
10 | const canvasWidth = (canvas as HTMLCanvasElement).width; | 9 | const canvasWidth = (canvas as HTMLCanvasElement).width; |
11 | const { | 10 | const { |
12 | logoSize = 0.15, | 11 | logoSize = 0.15, |
src/components/Qrcode/src/qrcodePlus.ts
src/components/Qrcode/src/toCanvas.ts
1 | import { renderQrCode } from './drawCanvas'; | 1 | import { renderQrCode } from './drawCanvas'; |
2 | import { drawLogo } from './drawLogo'; | 2 | import { drawLogo } from './drawLogo'; |
3 | -import { RenderQrCodeParams } from './types'; | 3 | +import { RenderQrCodeParams } from './typing'; |
4 | export const toCanvas = (options: RenderQrCodeParams) => { | 4 | export const toCanvas = (options: RenderQrCodeParams) => { |
5 | return renderQrCode(options) | 5 | return renderQrCode(options) |
6 | .then(() => { | 6 | .then(() => { |
src/components/Qrcode/src/types.ts renamed to src/components/Qrcode/src/typing.ts
src/layouts/default/header/components/lock/LockModal.vue
src/views/demo/comp/drawer/index.vue
@@ -8,10 +8,7 @@ | @@ -8,10 +8,7 @@ | ||
8 | <Alert message="自适应高度/显示footer" show-icon /> | 8 | <Alert message="自适应高度/显示footer" show-icon /> |
9 | <a-button type="primary" class="my-4" @click="openDrawer3(true)"> 打开Drawer </a-button> | 9 | <a-button type="primary" class="my-4" @click="openDrawer3(true)"> 打开Drawer </a-button> |
10 | 10 | ||
11 | - <Alert | ||
12 | - message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" | ||
13 | - show-icon | ||
14 | - /> | 11 | + <Alert message="内外数据交互" show-icon /> |
15 | <a-button type="primary" class="my-4" @click="send"> 打开Drawer并传递数据 </a-button> | 12 | <a-button type="primary" class="my-4" @click="send"> 打开Drawer并传递数据 </a-button> |
16 | <Alert message="详情页模式" show-icon /> | 13 | <Alert message="详情页模式" show-icon /> |
17 | <a-button type="primary" class="my-4" @click="openDrawer5(true)"> 打开详情Drawer </a-button> | 14 | <a-button type="primary" class="my-4" @click="openDrawer5(true)"> 打开详情Drawer </a-button> |
src/views/demo/comp/modal/index.vue
@@ -14,10 +14,7 @@ | @@ -14,10 +14,7 @@ | ||
14 | <Alert message="自适应高度" show-icon /> | 14 | <Alert message="自适应高度" show-icon /> |
15 | <a-button type="primary" class="my-4" @click="openModal3"> 打开弹窗 </a-button> | 15 | <a-button type="primary" class="my-4" @click="openModal3"> 打开弹窗 </a-button> |
16 | 16 | ||
17 | - <Alert | ||
18 | - message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式" | ||
19 | - show-icon | ||
20 | - /> | 17 | + <Alert message="内外数据交互" show-icon /> |
21 | <a-button type="primary" class="my-4" @click="send"> 打开弹窗并传递数据 </a-button> | 18 | <a-button type="primary" class="my-4" @click="send"> 打开弹窗并传递数据 </a-button> |
22 | 19 | ||
23 | <Modal1 @register="register1" :minHeight="100" /> | 20 | <Modal1 @register="register1" :minHeight="100" /> |
types/global.d.ts
1 | import type { | 1 | import type { |
2 | ComponentRenderProxy, | 2 | ComponentRenderProxy, |
3 | VNode, | 3 | VNode, |
4 | + VNodeChild, | ||
4 | ComponentPublicInstance, | 5 | ComponentPublicInstance, |
5 | FunctionalComponent, | 6 | FunctionalComponent, |
6 | PropType as VuePropType, | 7 | PropType as VuePropType, |
@@ -23,6 +24,7 @@ declare global { | @@ -23,6 +24,7 @@ declare global { | ||
23 | 24 | ||
24 | // vue | 25 | // vue |
25 | declare type PropType<T> = VuePropType<T>; | 26 | declare type PropType<T> = VuePropType<T>; |
27 | + declare type VueNode = VNodeChild | JSX.Element; | ||
26 | 28 | ||
27 | export type Writable<T> = { | 29 | export type Writable<T> = { |
28 | -readonly [P in keyof T]: T[P]; | 30 | -readonly [P in keyof T]: T[P]; |