Commit fb0c7763eddde38d3746cb424ebe9662ac576c86
1 parent
2f1fbf8e
fix(modal): fix modal not showing footer
Showing
12 changed files
with
130 additions
and
115 deletions
CHANGELOG.zh_CN.md
1 | ## Wip | 1 | ## Wip |
2 | 2 | ||
3 | +### 🎫 Chores | ||
4 | + | ||
5 | +- 添加部分注释 | ||
6 | +- pwa 图标补充 | ||
7 | +- types 类型调整 | ||
8 | + | ||
3 | ### 🐛 Bug Fixes | 9 | ### 🐛 Bug Fixes |
4 | 10 | ||
5 | - 修复本地代理 post 接口到 https 地址超时错误 | 11 | - 修复本地代理 post 接口到 https 地址超时错误 |
12 | +- 修复 modal 在不显示 footer 的时候全屏高度计算问题 | ||
6 | 13 | ||
7 | ## 2.0.0-rc.6 (2020-10-28) | 14 | ## 2.0.0-rc.6 (2020-10-28) |
8 | 15 |
src/components/Authority/src/index.vue
1 | <script lang="ts"> | 1 | <script lang="ts"> |
2 | - import { defineComponent, PropType, computed, unref } from 'vue'; | 2 | + import type { PropType } from 'vue'; |
3 | + import { defineComponent, computed, unref } from 'vue'; | ||
3 | 4 | ||
4 | import { PermissionModeEnum } from '/@/enums/appEnum'; | 5 | import { PermissionModeEnum } from '/@/enums/appEnum'; |
5 | import { RoleEnum } from '/@/enums/roleEnum'; | 6 | import { RoleEnum } from '/@/enums/roleEnum'; |
src/components/Basic/src/BasicArrow.vue
@@ -7,11 +7,10 @@ | @@ -7,11 +7,10 @@ | ||
7 | import type { PropType } from 'vue'; | 7 | import type { PropType } from 'vue'; |
8 | 8 | ||
9 | import { defineComponent, computed } from 'vue'; | 9 | import { defineComponent, computed } from 'vue'; |
10 | - | ||
11 | import { RightOutlined } from '@ant-design/icons-vue'; | 10 | import { RightOutlined } from '@ant-design/icons-vue'; |
12 | 11 | ||
13 | export default defineComponent({ | 12 | export default defineComponent({ |
14 | - name: 'BaseArrow', | 13 | + name: 'BasicArrow', |
15 | components: { RightOutlined }, | 14 | components: { RightOutlined }, |
16 | props: { | 15 | props: { |
17 | // Expand contract, expand by default | 16 | // Expand contract, expand by default |
@@ -24,7 +23,6 @@ | @@ -24,7 +23,6 @@ | ||
24 | const getClass = computed(() => { | 23 | const getClass = computed(() => { |
25 | const preCls = 'base-arrow'; | 24 | const preCls = 'base-arrow'; |
26 | const cls = [preCls]; | 25 | const cls = [preCls]; |
27 | - | ||
28 | props.expand && cls.push(`${preCls}__active`); | 26 | props.expand && cls.push(`${preCls}__active`); |
29 | return cls; | 27 | return cls; |
30 | }); | 28 | }); |
src/components/Basic/src/BasicHelp.vue
1 | <script lang="ts"> | 1 | <script lang="ts"> |
2 | import type { PropType } from 'vue'; | 2 | import type { PropType } from 'vue'; |
3 | + import { defineComponent, computed, unref, h } from 'vue'; | ||
3 | 4 | ||
4 | import { Tooltip } from 'ant-design-vue'; | 5 | import { Tooltip } from 'ant-design-vue'; |
5 | import { InfoCircleOutlined } from '@ant-design/icons-vue'; | 6 | import { InfoCircleOutlined } from '@ant-design/icons-vue'; |
6 | - import { defineComponent, computed, unref, h } from 'vue'; | ||
7 | 7 | ||
8 | import { getPopupContainer } from '/@/utils'; | 8 | import { getPopupContainer } from '/@/utils'; |
9 | - | ||
10 | import { isString, isArray } from '/@/utils/is'; | 9 | import { isString, isArray } from '/@/utils/is'; |
11 | import { getSlot } from '/@/utils/helper/tsxHelper'; | 10 | import { getSlot } from '/@/utils/helper/tsxHelper'; |
12 | export default defineComponent({ | 11 | export default defineComponent({ |
13 | - name: 'BaseHelp', | 12 | + name: 'BasicHelp', |
14 | components: { Tooltip }, | 13 | components: { Tooltip }, |
15 | props: { | 14 | props: { |
16 | // max-width | 15 | // max-width |
@@ -56,12 +55,14 @@ | @@ -56,12 +55,14 @@ | ||
56 | maxWidth: props.maxWidth, | 55 | maxWidth: props.maxWidth, |
57 | }; | 56 | }; |
58 | }); | 57 | }); |
58 | + | ||
59 | const getWrapStyleRef = computed(() => { | 59 | const getWrapStyleRef = computed(() => { |
60 | return { | 60 | return { |
61 | color: props.color, | 61 | color: props.color, |
62 | fontSize: props.fontSize, | 62 | fontSize: props.fontSize, |
63 | }; | 63 | }; |
64 | }); | 64 | }); |
65 | + | ||
65 | const getMainStyleRef = computed(() => { | 66 | const getMainStyleRef = computed(() => { |
66 | return props.absolute ? props.position : {}; | 67 | return props.absolute ? props.position : {}; |
67 | }); | 68 | }); |
@@ -81,6 +82,7 @@ | @@ -81,6 +82,7 @@ | ||
81 | } | 82 | } |
82 | return null; | 83 | return null; |
83 | }; | 84 | }; |
85 | + | ||
84 | return () => { | 86 | return () => { |
85 | return h( | 87 | return h( |
86 | Tooltip, | 88 | Tooltip, |
src/components/Basic/src/BasicTitle.vue
1 | <template> | 1 | <template> |
2 | <span class="base-title" :class="{ 'show-span': showSpan && $slots.default }"> | 2 | <span class="base-title" :class="{ 'show-span': showSpan && $slots.default }"> |
3 | <slot /> | 3 | <slot /> |
4 | - <BaseHelp class="base-title__help" v-if="helpMessage" :text="helpMessage" /> | 4 | + <BasicHelp class="base-title__help" v-if="helpMessage" :text="helpMessage" /> |
5 | </span> | 5 | </span> |
6 | </template> | 6 | </template> |
7 | <script lang="ts"> | 7 | <script lang="ts"> |
@@ -9,8 +9,11 @@ | @@ -9,8 +9,11 @@ | ||
9 | 9 | ||
10 | import { defineComponent } from 'vue'; | 10 | import { defineComponent } from 'vue'; |
11 | 11 | ||
12 | + import BasicHelp from './BasicHelp.vue'; | ||
13 | + | ||
12 | export default defineComponent({ | 14 | export default defineComponent({ |
13 | - name: 'BaseTitle', | 15 | + name: 'BasicTitle', |
16 | + components: { BasicHelp }, | ||
14 | props: { | 17 | props: { |
15 | helpMessage: { | 18 | helpMessage: { |
16 | type: [String, Array] as PropType<string | string[]>, | 19 | type: [String, Array] as PropType<string | string[]>, |
src/components/Breadcrumb/BreadcrumbItem.vue
@@ -31,10 +31,12 @@ | @@ -31,10 +31,12 @@ | ||
31 | }, | 31 | }, |
32 | setup(props) { | 32 | setup(props) { |
33 | const linkRef = ref<Nullable<HTMLElement>>(null); | 33 | const linkRef = ref<Nullable<HTMLElement>>(null); |
34 | + | ||
34 | const parent = inject('breadcrumb') as { | 35 | const parent = inject('breadcrumb') as { |
35 | separator: string; | 36 | separator: string; |
36 | separatorClass: string; | 37 | separatorClass: string; |
37 | }; | 38 | }; |
39 | + | ||
38 | const { push, replace } = useRouter(); | 40 | const { push, replace } = useRouter(); |
39 | 41 | ||
40 | onMounted(() => { | 42 | onMounted(() => { |
src/components/Modal/src/BasicModal.tsx
1 | import type { ModalProps, ModalMethods } from './types'; | 1 | import type { ModalProps, ModalMethods } from './types'; |
2 | 2 | ||
3 | +import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue'; | ||
4 | + | ||
3 | import Modal from './Modal'; | 5 | import Modal from './Modal'; |
4 | -import { Button } from 'ant-design-vue'; | 6 | +import Button from '/@/components/Button/index.vue'; |
5 | import ModalWrapper from './ModalWrapper'; | 7 | import ModalWrapper from './ModalWrapper'; |
6 | import { BasicTitle } from '/@/components/Basic'; | 8 | import { BasicTitle } from '/@/components/Basic'; |
7 | -import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue'; | ||
8 | - | ||
9 | import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue'; | 9 | import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue'; |
10 | 10 | ||
11 | -import { basicProps } from './props'; | ||
12 | - | ||
13 | import { getSlot, extendSlots } from '/@/utils/helper/tsxHelper'; | 11 | import { getSlot, extendSlots } from '/@/utils/helper/tsxHelper'; |
14 | import { isFunction } from '/@/utils/is'; | 12 | import { isFunction } from '/@/utils/is'; |
15 | import { deepMerge } from '/@/utils'; | 13 | import { deepMerge } from '/@/utils'; |
16 | import { buildUUID } from '/@/utils/uuid'; | 14 | import { buildUUID } from '/@/utils/uuid'; |
17 | 15 | ||
16 | +import { basicProps } from './props'; | ||
18 | // import { triggerWindowResize } from '@/utils/event/triggerWindowResizeEvent'; | 17 | // import { triggerWindowResize } from '@/utils/event/triggerWindowResizeEvent'; |
19 | export default defineComponent({ | 18 | export default defineComponent({ |
20 | name: 'BasicModal', | 19 | name: 'BasicModal', |
@@ -22,18 +21,14 @@ export default defineComponent({ | @@ -22,18 +21,14 @@ export default defineComponent({ | ||
22 | emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register'], | 21 | emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register'], |
23 | setup(props, { slots, emit, attrs }) { | 22 | setup(props, { slots, emit, attrs }) { |
24 | const visibleRef = ref(false); | 23 | const visibleRef = ref(false); |
25 | - | ||
26 | const propsRef = ref<Partial<ModalProps> | null>(null); | 24 | const propsRef = ref<Partial<ModalProps> | null>(null); |
27 | - | ||
28 | const modalWrapperRef = ref<any>(null); | 25 | const modalWrapperRef = ref<any>(null); |
29 | - | ||
30 | // modal Bottom and top height | 26 | // modal Bottom and top height |
31 | const extHeightRef = ref(0); | 27 | const extHeightRef = ref(0); |
32 | - | ||
33 | // Unexpanded height of the popup | 28 | // Unexpanded height of the popup |
34 | const formerHeightRef = ref(0); | 29 | const formerHeightRef = ref(0); |
35 | - | ||
36 | const fullScreenRef = ref(false); | 30 | const fullScreenRef = ref(false); |
31 | + | ||
37 | // Custom title component: get title | 32 | // Custom title component: get title |
38 | const getMergeProps = computed(() => { | 33 | const getMergeProps = computed(() => { |
39 | return { | 34 | return { |
@@ -41,6 +36,7 @@ export default defineComponent({ | @@ -41,6 +36,7 @@ export default defineComponent({ | ||
41 | ...(unref(propsRef) as any), | 36 | ...(unref(propsRef) as any), |
42 | }; | 37 | }; |
43 | }); | 38 | }); |
39 | + | ||
44 | // modal component does not need title | 40 | // modal component does not need title |
45 | const getProps = computed((): any => { | 41 | const getProps = computed((): any => { |
46 | const opt = { | 42 | const opt = { |
@@ -56,9 +52,11 @@ export default defineComponent({ | @@ -56,9 +52,11 @@ export default defineComponent({ | ||
56 | wrapClassName: className, | 52 | wrapClassName: className, |
57 | }; | 53 | }; |
58 | }); | 54 | }); |
55 | + | ||
59 | watchEffect(() => { | 56 | watchEffect(() => { |
60 | visibleRef.value = !!props.visible; | 57 | visibleRef.value = !!props.visible; |
61 | }); | 58 | }); |
59 | + | ||
62 | watch( | 60 | watch( |
63 | () => unref(visibleRef), | 61 | () => unref(visibleRef), |
64 | (v) => { | 62 | (v) => { |
@@ -68,6 +66,7 @@ export default defineComponent({ | @@ -68,6 +66,7 @@ export default defineComponent({ | ||
68 | immediate: false, | 66 | immediate: false, |
69 | } | 67 | } |
70 | ); | 68 | ); |
69 | + | ||
71 | /** | 70 | /** |
72 | * @description: 渲染标题 | 71 | * @description: 渲染标题 |
73 | */ | 72 | */ |
@@ -83,13 +82,17 @@ export default defineComponent({ | @@ -83,13 +82,17 @@ export default defineComponent({ | ||
83 | 82 | ||
84 | function renderContent() { | 83 | function renderContent() { |
85 | const { useWrapper, loading, wrapperProps } = unref(getProps); | 84 | const { useWrapper, loading, wrapperProps } = unref(getProps); |
86 | - return useWrapper ? ( | 85 | + if (!useWrapper) return getSlot(slots); |
86 | + | ||
87 | + const showFooter = props.footer !== undefined && !props.footer ? 0 : undefined; | ||
88 | + return ( | ||
87 | <ModalWrapper | 89 | <ModalWrapper |
88 | footerOffset={props.wrapperFooterOffset} | 90 | footerOffset={props.wrapperFooterOffset} |
89 | fullScreen={unref(fullScreenRef)} | 91 | fullScreen={unref(fullScreenRef)} |
90 | ref={modalWrapperRef} | 92 | ref={modalWrapperRef} |
91 | loading={loading} | 93 | loading={loading} |
92 | visible={unref(visibleRef)} | 94 | visible={unref(visibleRef)} |
95 | + modalFooterHeight={showFooter} | ||
93 | {...wrapperProps} | 96 | {...wrapperProps} |
94 | onGetExtHeight={(height: number) => { | 97 | onGetExtHeight={(height: number) => { |
95 | extHeightRef.value = height; | 98 | extHeightRef.value = height; |
@@ -100,13 +103,12 @@ export default defineComponent({ | @@ -100,13 +103,12 @@ export default defineComponent({ | ||
100 | > | 103 | > |
101 | {() => getSlot(slots)} | 104 | {() => getSlot(slots)} |
102 | </ModalWrapper> | 105 | </ModalWrapper> |
103 | - ) : ( | ||
104 | - getSlot(slots) | ||
105 | ); | 106 | ); |
106 | } | 107 | } |
108 | + | ||
107 | // 取消事件 | 109 | // 取消事件 |
108 | async function handleCancel(e: Event) { | 110 | async function handleCancel(e: Event) { |
109 | - e.stopPropagation(); | 111 | + e && e.stopPropagation(); |
110 | if (props.closeFunc && isFunction(props.closeFunc)) { | 112 | if (props.closeFunc && isFunction(props.closeFunc)) { |
111 | const isClose: boolean = await props.closeFunc(); | 113 | const isClose: boolean = await props.closeFunc(); |
112 | visibleRef.value = !isClose; | 114 | visibleRef.value = !isClose; |
@@ -115,6 +117,7 @@ export default defineComponent({ | @@ -115,6 +117,7 @@ export default defineComponent({ | ||
115 | visibleRef.value = false; | 117 | visibleRef.value = false; |
116 | emit('cancel'); | 118 | emit('cancel'); |
117 | } | 119 | } |
120 | + | ||
118 | // 底部按钮自定义实现, | 121 | // 底部按钮自定义实现, |
119 | function renderFooter() { | 122 | function renderFooter() { |
120 | const { | 123 | const { |
@@ -131,7 +134,6 @@ export default defineComponent({ | @@ -131,7 +134,6 @@ export default defineComponent({ | ||
131 | return ( | 134 | return ( |
132 | <> | 135 | <> |
133 | {getSlot(slots, 'insertFooter')} | 136 | {getSlot(slots, 'insertFooter')} |
134 | - | ||
135 | {showCancelBtn && ( | 137 | {showCancelBtn && ( |
136 | <Button {...cancelButtonProps} onClick={handleCancel}> | 138 | <Button {...cancelButtonProps} onClick={handleCancel}> |
137 | {() => cancelText} | 139 | {() => cancelText} |
@@ -150,11 +152,11 @@ export default defineComponent({ | @@ -150,11 +152,11 @@ export default defineComponent({ | ||
150 | {() => okText} | 152 | {() => okText} |
151 | </Button> | 153 | </Button> |
152 | )} | 154 | )} |
153 | - | ||
154 | {getSlot(slots, 'appendFooter')} | 155 | {getSlot(slots, 'appendFooter')} |
155 | </> | 156 | </> |
156 | ); | 157 | ); |
157 | } | 158 | } |
159 | + | ||
158 | /** | 160 | /** |
159 | * @description: 关闭按钮 | 161 | * @description: 关闭按钮 |
160 | */ | 162 | */ |
@@ -176,27 +178,26 @@ export default defineComponent({ | @@ -176,27 +178,26 @@ export default defineComponent({ | ||
176 | } | 178 | } |
177 | 179 | ||
178 | function handleFullScreen(e: Event) { | 180 | function handleFullScreen(e: Event) { |
179 | - e.stopPropagation(); | 181 | + e && e.stopPropagation(); |
180 | fullScreenRef.value = !unref(fullScreenRef); | 182 | fullScreenRef.value = !unref(fullScreenRef); |
181 | 183 | ||
182 | const modalWrapper = unref(modalWrapperRef); | 184 | const modalWrapper = unref(modalWrapperRef); |
183 | - if (modalWrapper) { | ||
184 | - const modalWrapSpinEl = (modalWrapper.$el as HTMLElement).querySelector( | ||
185 | - '.ant-spin-nested-loading' | ||
186 | - ); | ||
187 | - if (modalWrapSpinEl) { | ||
188 | - if (!unref(formerHeightRef) && unref(fullScreenRef)) { | ||
189 | - formerHeightRef.value = (modalWrapSpinEl as HTMLElement).offsetHeight; | ||
190 | - console.log(formerHeightRef); | ||
191 | - } | ||
192 | - if (unref(fullScreenRef)) { | ||
193 | - (modalWrapSpinEl as HTMLElement).style.height = `${ | ||
194 | - window.innerHeight - unref(extHeightRef) | ||
195 | - }px`; | ||
196 | - } else { | ||
197 | - (modalWrapSpinEl as HTMLElement).style.height = `${unref(formerHeightRef)}px`; | ||
198 | - } | ||
199 | - } | 185 | + if (!modalWrapper) return; |
186 | + | ||
187 | + const wrapperEl = modalWrapper.$el as HTMLElement; | ||
188 | + if (!wrapperEl) return; | ||
189 | + | ||
190 | + const modalWrapSpinEl = wrapperEl.querySelector('.ant-spin-nested-loading') as HTMLElement; | ||
191 | + if (!modalWrapSpinEl) return; | ||
192 | + | ||
193 | + if (!unref(formerHeightRef) && unref(fullScreenRef)) { | ||
194 | + formerHeightRef.value = modalWrapSpinEl.offsetHeight; | ||
195 | + } | ||
196 | + | ||
197 | + if (unref(fullScreenRef)) { | ||
198 | + modalWrapSpinEl.style.height = `${window.innerHeight - unref(extHeightRef)}px`; | ||
199 | + } else { | ||
200 | + modalWrapSpinEl.style.height = `${unref(formerHeightRef)}px`; | ||
200 | } | 201 | } |
201 | } | 202 | } |
202 | 203 | ||
@@ -206,21 +207,22 @@ export default defineComponent({ | @@ -206,21 +207,22 @@ export default defineComponent({ | ||
206 | function setModalProps(props: Partial<ModalProps>): void { | 207 | function setModalProps(props: Partial<ModalProps>): void { |
207 | // Keep the last setModalProps | 208 | // Keep the last setModalProps |
208 | propsRef.value = deepMerge(unref(propsRef) || {}, props); | 209 | propsRef.value = deepMerge(unref(propsRef) || {}, props); |
209 | - if (Reflect.has(props, 'visible')) { | ||
210 | - visibleRef.value = !!props.visible; | ||
211 | - } | 210 | + if (!Reflect.has(props, 'visible')) return; |
211 | + visibleRef.value = !!props.visible; | ||
212 | } | 212 | } |
213 | 213 | ||
214 | const modalMethods: ModalMethods = { | 214 | const modalMethods: ModalMethods = { |
215 | setModalProps, | 215 | setModalProps, |
216 | }; | 216 | }; |
217 | + | ||
217 | const uuid = buildUUID(); | 218 | const uuid = buildUUID(); |
218 | emit('register', modalMethods, uuid); | 219 | emit('register', modalMethods, uuid); |
220 | + | ||
219 | return () => ( | 221 | return () => ( |
220 | <Modal | 222 | <Modal |
221 | onCancel={handleCancel} | 223 | onCancel={handleCancel} |
222 | - {...{ ...attrs, ...props, ...unref(getProps) }} | ||
223 | getContainer={() => document.querySelector('.default-layout__main')} | 224 | getContainer={() => document.querySelector('.default-layout__main')} |
225 | + {...{ ...attrs, ...props, ...unref(getProps) }} | ||
224 | > | 226 | > |
225 | {{ | 227 | {{ |
226 | ...extendSlots(slots, ['default']), | 228 | ...extendSlots(slots, ['default']), |
src/components/Modal/src/Modal.tsx
@@ -23,6 +23,7 @@ export default defineComponent({ | @@ -23,6 +23,7 @@ export default defineComponent({ | ||
23 | dialogHeaderEl.style.cursor = 'move'; | 23 | dialogHeaderEl.style.cursor = 'move'; |
24 | 24 | ||
25 | dialogHeaderEl.onmousedown = (e: any) => { | 25 | dialogHeaderEl.onmousedown = (e: any) => { |
26 | + if (!e) return; | ||
26 | // 鼠标按下,计算当前元素距离可视区的距离 | 27 | // 鼠标按下,计算当前元素距离可视区的距离 |
27 | const disX = e.clientX; | 28 | const disX = e.clientX; |
28 | const disY = e.clientY; | 29 | const disY = e.clientY; |
@@ -84,8 +85,8 @@ export default defineComponent({ | @@ -84,8 +85,8 @@ export default defineComponent({ | ||
84 | const handleDrag = () => { | 85 | const handleDrag = () => { |
85 | const dragWraps = document.querySelectorAll('.ant-modal-wrap'); | 86 | const dragWraps = document.querySelectorAll('.ant-modal-wrap'); |
86 | for (const wrap of dragWraps as any) { | 87 | for (const wrap of dragWraps as any) { |
88 | + if (!wrap) continue; | ||
87 | const display = getStyle(wrap, 'display'); | 89 | const display = getStyle(wrap, 'display'); |
88 | - | ||
89 | const draggable = wrap.getAttribute('data-drag'); | 90 | const draggable = wrap.getAttribute('data-drag'); |
90 | if (display !== 'none') { | 91 | if (display !== 'none') { |
91 | // 拖拽位置 | 92 | // 拖拽位置 |
@@ -98,7 +99,6 @@ export default defineComponent({ | @@ -98,7 +99,6 @@ export default defineComponent({ | ||
98 | if (!props.visible) { | 99 | if (!props.visible) { |
99 | return; | 100 | return; |
100 | } | 101 | } |
101 | - // context.$nextTick(); | ||
102 | useTimeout(() => { | 102 | useTimeout(() => { |
103 | handleDrag(); | 103 | handleDrag(); |
104 | }, 30); | 104 | }, 30); |
src/components/Modal/src/ModalWrapper.tsx
@@ -13,10 +13,9 @@ import { | @@ -13,10 +13,9 @@ import { | ||
13 | onUnmounted, | 13 | onUnmounted, |
14 | } from 'vue'; | 14 | } from 'vue'; |
15 | import { Spin } from 'ant-design-vue'; | 15 | import { Spin } from 'ant-design-vue'; |
16 | -import { ScrollContainer } from '/@/components/Container/index'; | ||
17 | 16 | ||
18 | import { useWindowSizeFn } from '/@/hooks/event/useWindowSize'; | 17 | import { useWindowSizeFn } from '/@/hooks/event/useWindowSize'; |
19 | -import { useTimeout } from '/@/hooks/core/useTimeout'; | 18 | +// import { useTimeout } from '/@/hooks/core/useTimeout'; |
20 | 19 | ||
21 | import { getSlot } from '/@/utils/helper/tsxHelper'; | 20 | import { getSlot } from '/@/utils/helper/tsxHelper'; |
22 | import { useElResize } from '/@/hooks/event/useElResize'; | 21 | import { useElResize } from '/@/hooks/event/useElResize'; |
@@ -61,26 +60,46 @@ export default defineComponent({ | @@ -61,26 +60,46 @@ export default defineComponent({ | ||
61 | const wrapStyle = computed(() => { | 60 | const wrapStyle = computed(() => { |
62 | return { | 61 | return { |
63 | minHeight: `${props.minHeight}px`, | 62 | minHeight: `${props.minHeight}px`, |
64 | - overflow: 'hidden', | 63 | + height: `${unref(realHeightRef)}px`, |
64 | + overflow: 'auto', | ||
65 | }; | 65 | }; |
66 | }); | 66 | }); |
67 | 67 | ||
68 | // 重试次数 | 68 | // 重试次数 |
69 | - let tryCount = 0; | 69 | + // let tryCount = 0; |
70 | + let stopElResizeFn: Fn = () => {}; | ||
71 | + | ||
72 | + watchEffect(() => { | ||
73 | + setModalHeight(); | ||
74 | + }); | ||
75 | + | ||
76 | + watch( | ||
77 | + () => props.fullScreen, | ||
78 | + (v) => { | ||
79 | + !v && setModalHeight(); | ||
80 | + } | ||
81 | + ); | ||
82 | + | ||
83 | + onMounted(() => { | ||
84 | + const { modalHeaderHeight, modalFooterHeight } = props; | ||
85 | + emit('getExtHeight', modalHeaderHeight + modalFooterHeight); | ||
86 | + listenElResize(); | ||
87 | + }); | ||
88 | + | ||
89 | + onUnmounted(() => { | ||
90 | + stopElResizeFn && stopElResizeFn(); | ||
91 | + }); | ||
92 | + | ||
93 | + useWindowSizeFn(setModalHeight); | ||
94 | + | ||
70 | async function setModalHeight() { | 95 | async function setModalHeight() { |
71 | // 解决在弹窗关闭的时候监听还存在,导致再次打开弹窗没有高度 | 96 | // 解决在弹窗关闭的时候监听还存在,导致再次打开弹窗没有高度 |
72 | // 加上这个,就必须在使用的时候传递父级的visible | 97 | // 加上这个,就必须在使用的时候传递父级的visible |
73 | - if (!props.visible) { | ||
74 | - return; | ||
75 | - } | 98 | + if (!props.visible) return; |
76 | const wrapperRefDom = unref(wrapperRef); | 99 | const wrapperRefDom = unref(wrapperRef); |
77 | - if (!wrapperRefDom) { | ||
78 | - return; | ||
79 | - } | 100 | + if (!wrapperRefDom) return; |
80 | const bodyDom = wrapperRefDom.parentElement; | 101 | const bodyDom = wrapperRefDom.parentElement; |
81 | - if (!bodyDom) { | ||
82 | - return; | ||
83 | - } | 102 | + if (!bodyDom) return; |
84 | bodyDom.style.padding = '0'; | 103 | bodyDom.style.padding = '0'; |
85 | await nextTick(); | 104 | await nextTick(); |
86 | 105 | ||
@@ -104,23 +123,23 @@ export default defineComponent({ | @@ -104,23 +123,23 @@ export default defineComponent({ | ||
104 | } | 123 | } |
105 | await nextTick(); | 124 | await nextTick(); |
106 | const spinEl = unref(spinRef); | 125 | const spinEl = unref(spinRef); |
107 | - if (!spinEl) { | ||
108 | - useTimeout(() => { | ||
109 | - // retry | ||
110 | - if (tryCount < 3) { | ||
111 | - setModalHeight(); | ||
112 | - } | ||
113 | - tryCount++; | ||
114 | - }, 10); | ||
115 | - return; | ||
116 | - } | ||
117 | - tryCount = 0; | 126 | + // if (!spinEl) { |
127 | + // useTimeout(() => { | ||
128 | + // // retry | ||
129 | + // if (tryCount < 3) { | ||
130 | + // setModalHeight(); | ||
131 | + // } | ||
132 | + // tryCount++; | ||
133 | + // }, 10); | ||
134 | + // return; | ||
135 | + // } | ||
136 | + // tryCount = 0; | ||
118 | 137 | ||
119 | - const realHeight = (spinEl.$el.querySelector('.ant-spin-container') as HTMLElement) | ||
120 | - .scrollHeight; | 138 | + const spinContainerEl = spinEl.$el.querySelector('.ant-spin-container') as HTMLElement; |
139 | + if (!spinContainerEl) return; | ||
140 | + | ||
141 | + const realHeight = spinContainerEl.scrollHeight; | ||
121 | 142 | ||
122 | - // 16为 p-2和m-2 加起来为4,基础4, 4*4=16 | ||
123 | - // 32 padding | ||
124 | if (props.fullScreen) { | 143 | if (props.fullScreen) { |
125 | realHeightRef.value = | 144 | realHeightRef.value = |
126 | window.innerHeight - props.modalFooterHeight - props.modalHeaderHeight - 26; | 145 | window.innerHeight - props.modalFooterHeight - props.modalHeaderHeight - 26; |
@@ -138,6 +157,7 @@ export default defineComponent({ | @@ -138,6 +157,7 @@ export default defineComponent({ | ||
138 | console.log(error); | 157 | console.log(error); |
139 | } | 158 | } |
140 | } | 159 | } |
160 | + | ||
141 | function listenElResize() { | 161 | function listenElResize() { |
142 | const wrapper = unref(wrapperRef); | 162 | const wrapper = unref(wrapperRef); |
143 | if (!wrapper) return; | 163 | if (!wrapper) return; |
@@ -146,41 +166,16 @@ export default defineComponent({ | @@ -146,41 +166,16 @@ export default defineComponent({ | ||
146 | const [start, stop] = useElResize(container, () => { | 166 | const [start, stop] = useElResize(container, () => { |
147 | setModalHeight(); | 167 | setModalHeight(); |
148 | }); | 168 | }); |
169 | + stopElResizeFn = stop; | ||
149 | start(); | 170 | start(); |
150 | - onUnmounted(() => { | ||
151 | - stop(); | ||
152 | - }); | ||
153 | } | 171 | } |
154 | - nextTick(() => {}); | ||
155 | - watchEffect(() => { | ||
156 | - setModalHeight(); | ||
157 | - }); | ||
158 | - watch( | ||
159 | - () => props.fullScreen, | ||
160 | - (v) => { | ||
161 | - !v && setModalHeight(); | ||
162 | - } | ||
163 | - ); | ||
164 | - | ||
165 | - onMounted(() => { | ||
166 | - const { modalHeaderHeight, modalFooterHeight } = props; | ||
167 | - emit('getExtHeight', modalHeaderHeight + modalFooterHeight); | ||
168 | - listenElResize(); | ||
169 | - }); | ||
170 | - | ||
171 | - useWindowSizeFn(setModalHeight); | ||
172 | 172 | ||
173 | return () => { | 173 | return () => { |
174 | - const height = unref(realHeightRef); | ||
175 | return ( | 174 | return ( |
176 | <div ref={wrapperRef} style={unref(wrapStyle)}> | 175 | <div ref={wrapperRef} style={unref(wrapStyle)}> |
177 | - <ScrollContainer> | ||
178 | - {() => ( | ||
179 | - <Spin ref={spinRef} spinning={props.loading} style={{ height: `${height}px` }}> | ||
180 | - {() => getSlot(slots)} | ||
181 | - </Spin> | ||
182 | - )} | ||
183 | - </ScrollContainer> | 176 | + <Spin ref={spinRef} spinning={props.loading}> |
177 | + {() => getSlot(slots)} | ||
178 | + </Spin> | ||
184 | </div> | 179 | </div> |
185 | ); | 180 | ); |
186 | }; | 181 | }; |
src/components/Modal/src/index.less
@@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
26 | line-height: 16px; | 26 | line-height: 16px; |
27 | 27 | ||
28 | .base-title { | 28 | .base-title { |
29 | - cursor: move; | 29 | + cursor: move !important; |
30 | } | 30 | } |
31 | } | 31 | } |
32 | 32 | ||
@@ -56,7 +56,6 @@ | @@ -56,7 +56,6 @@ | ||
56 | } | 56 | } |
57 | 57 | ||
58 | .ant-modal-body { | 58 | .ant-modal-body { |
59 | - // background: #f1f2f6; | ||
60 | padding: 0; | 59 | padding: 0; |
61 | } | 60 | } |
62 | 61 | ||
@@ -69,7 +68,6 @@ | @@ -69,7 +68,6 @@ | ||
69 | } | 68 | } |
70 | 69 | ||
71 | &-header { | 70 | &-header { |
72 | - // padding: 12.5px 24px; | ||
73 | padding: 16px; | 71 | padding: 16px; |
74 | } | 72 | } |
75 | 73 | ||
@@ -79,7 +77,6 @@ | @@ -79,7 +77,6 @@ | ||
79 | 77 | ||
80 | &-footer { | 78 | &-footer { |
81 | padding: 10px 26px 26px 16px; | 79 | padding: 10px 26px 26px 16px; |
82 | - // border-top: none; | ||
83 | 80 | ||
84 | button + button { | 81 | button + button { |
85 | margin-left: 10px; | 82 | margin-left: 10px; |
src/components/Modal/src/useModal.ts
@@ -21,15 +21,15 @@ export function useModal(): UseModalReturnType { | @@ -21,15 +21,15 @@ export function useModal(): UseModalReturnType { | ||
21 | const uidRef = ref<string>(''); | 21 | const uidRef = ref<string>(''); |
22 | function register(modalMethod: ModalMethods, uuid: string) { | 22 | function register(modalMethod: ModalMethods, uuid: string) { |
23 | uidRef.value = uuid; | 23 | uidRef.value = uuid; |
24 | + | ||
24 | isProdMode() && | 25 | isProdMode() && |
25 | onUnmounted(() => { | 26 | onUnmounted(() => { |
26 | modalRef.value = null; | 27 | modalRef.value = null; |
27 | loadedRef.value = false; | 28 | loadedRef.value = false; |
28 | dataTransferRef[unref(uidRef)] = null; | 29 | dataTransferRef[unref(uidRef)] = null; |
29 | }); | 30 | }); |
30 | - if (unref(loadedRef) && isProdMode() && modalMethod === unref(modalRef)) { | ||
31 | - return; | ||
32 | - } | 31 | + if (unref(loadedRef) && isProdMode() && modalMethod === unref(modalRef)) return; |
32 | + | ||
33 | modalRef.value = modalMethod; | 33 | modalRef.value = modalMethod; |
34 | } | 34 | } |
35 | const getInstance = () => { | 35 | const getInstance = () => { |
@@ -44,11 +44,13 @@ export function useModal(): UseModalReturnType { | @@ -44,11 +44,13 @@ export function useModal(): UseModalReturnType { | ||
44 | setModalProps: (props: Partial<ModalProps>): void => { | 44 | setModalProps: (props: Partial<ModalProps>): void => { |
45 | getInstance().setModalProps(props); | 45 | getInstance().setModalProps(props); |
46 | }, | 46 | }, |
47 | + | ||
47 | openModal: (visible = true): void => { | 48 | openModal: (visible = true): void => { |
48 | getInstance().setModalProps({ | 49 | getInstance().setModalProps({ |
49 | visible: visible, | 50 | visible: visible, |
50 | }); | 51 | }); |
51 | }, | 52 | }, |
53 | + | ||
52 | transferModalData(val: any) { | 54 | transferModalData(val: any) { |
53 | dataTransferRef[unref(uidRef)] = val; | 55 | dataTransferRef[unref(uidRef)] = val; |
54 | }, | 56 | }, |
@@ -64,6 +66,7 @@ export const useModalInner = (): UseModalInnerReturnType => { | @@ -64,6 +66,7 @@ export const useModalInner = (): UseModalInnerReturnType => { | ||
64 | if (!currentInstall) { | 66 | if (!currentInstall) { |
65 | throw new Error('instance is undefined!'); | 67 | throw new Error('instance is undefined!'); |
66 | } | 68 | } |
69 | + | ||
67 | const getInstance = () => { | 70 | const getInstance = () => { |
68 | const instance = unref(modalInstanceRef); | 71 | const instance = unref(modalInstanceRef); |
69 | if (!instance) { | 72 | if (!instance) { |
@@ -71,26 +74,32 @@ export const useModalInner = (): UseModalInnerReturnType => { | @@ -71,26 +74,32 @@ export const useModalInner = (): UseModalInnerReturnType => { | ||
71 | } | 74 | } |
72 | return instance; | 75 | return instance; |
73 | }; | 76 | }; |
77 | + | ||
74 | const register = (modalInstance: ModalMethods, uuid: string) => { | 78 | const register = (modalInstance: ModalMethods, uuid: string) => { |
75 | uidRef.value = uuid; | 79 | uidRef.value = uuid; |
76 | modalInstanceRef.value = modalInstance; | 80 | modalInstanceRef.value = modalInstance; |
77 | currentInstall.emit('register', modalInstance); | 81 | currentInstall.emit('register', modalInstance); |
78 | }; | 82 | }; |
83 | + | ||
79 | return [ | 84 | return [ |
80 | register, | 85 | register, |
81 | { | 86 | { |
82 | receiveModalDataRef: computed(() => { | 87 | receiveModalDataRef: computed(() => { |
83 | return dataTransferRef[unref(uidRef)]; | 88 | return dataTransferRef[unref(uidRef)]; |
84 | }), | 89 | }), |
90 | + | ||
85 | changeLoading: (loading = true) => { | 91 | changeLoading: (loading = true) => { |
86 | getInstance().setModalProps({ loading }); | 92 | getInstance().setModalProps({ loading }); |
87 | }, | 93 | }, |
94 | + | ||
88 | changeOkLoading: (loading = true) => { | 95 | changeOkLoading: (loading = true) => { |
89 | getInstance().setModalProps({ confirmLoading: loading }); | 96 | getInstance().setModalProps({ confirmLoading: loading }); |
90 | }, | 97 | }, |
98 | + | ||
91 | closeModal: () => { | 99 | closeModal: () => { |
92 | getInstance().setModalProps({ visible: false }); | 100 | getInstance().setModalProps({ visible: false }); |
93 | }, | 101 | }, |
102 | + | ||
94 | setModalProps: (props: Partial<ModalProps>) => { | 103 | setModalProps: (props: Partial<ModalProps>) => { |
95 | getInstance().setModalProps(props); | 104 | getInstance().setModalProps(props); |
96 | }, | 105 | }, |
src/components/registerGlobComp.ts
1 | import Icon from './Icon/index'; | 1 | import Icon from './Icon/index'; |
2 | -import { BasicHelp, BasicTitle } from './Basic'; | ||
3 | import Button from './Button/index.vue'; | 2 | import Button from './Button/index.vue'; |
4 | import { Button as AntButton } from 'ant-design-vue'; | 3 | import { Button as AntButton } from 'ant-design-vue'; |
5 | import { getApp } from '/@/useApp'; | 4 | import { getApp } from '/@/useApp'; |
6 | 5 | ||
7 | -const compList = [Icon, BasicHelp, BasicTitle, Button, AntButton.Group]; | 6 | +const compList = [Icon, Button, AntButton.Group]; |
8 | 7 | ||
9 | // Fix hmr multiple registered components | 8 | // Fix hmr multiple registered components |
10 | let registered = false; | 9 | let registered = false; |