Commit a3a903bc86e7248424f94f734d21c86c5327ed20

Authored by vben
1 parent 33b2365f

feat(modal): exporse redoModalHeight

CHANGELOG.zh_CN.md
1 ## Wip 1 ## Wip
2 2
  3 +### ✨ Features
  4 +
  5 +- useModal 新增返回值函数 `redoModalHeight`,用于在 modal 内为动态内容时刷新 modal 高度
  6 +
3 ### 🐛 Bug Fixes 7 ### 🐛 Bug Fixes
4 8
5 - 修复 Upload 组件 maxNumber 失效问题 9 - 修复 Upload 组件 maxNumber 失效问题
src/components/Modal/src/BasicModal.vue
@@ -55,6 +55,7 @@ @@ -55,6 +55,7 @@
55 watchEffect, 55 watchEffect,
56 toRef, 56 toRef,
57 getCurrentInstance, 57 getCurrentInstance,
  58 + nextTick,
58 } from 'vue'; 59 } from 'vue';
59 60
60 import Modal from './components/Modal'; 61 import Modal from './components/Modal';
@@ -68,6 +69,7 @@ @@ -68,6 +69,7 @@
68 69
69 import { basicProps } from './props'; 70 import { basicProps } from './props';
70 import { useFullScreen } from './hooks/useModalFullScreen'; 71 import { useFullScreen } from './hooks/useModalFullScreen';
  72 +
71 import { omit } from 'lodash-es'; 73 import { omit } from 'lodash-es';
72 export default defineComponent({ 74 export default defineComponent({
73 name: 'BasicModal', 75 name: 'BasicModal',
@@ -79,12 +81,21 @@ @@ -79,12 +81,21 @@
79 const visibleRef = ref(false); 81 const visibleRef = ref(false);
80 const propsRef = ref<Partial<ModalProps> | null>(null); 82 const propsRef = ref<Partial<ModalProps> | null>(null);
81 const modalWrapperRef = ref<ComponentRef>(null); 83 const modalWrapperRef = ref<ComponentRef>(null);
  84 +
82 // modal Bottom and top height 85 // modal Bottom and top height
83 const extHeightRef = ref(0); 86 const extHeightRef = ref(0);
84 const modalMethods: ModalMethods = { 87 const modalMethods: ModalMethods = {
85 setModalProps, 88 setModalProps,
86 emitVisible: undefined, 89 emitVisible: undefined,
  90 + redoModalHeight: () => {
  91 + nextTick(() => {
  92 + if (unref(modalWrapperRef)) {
  93 + (unref(modalWrapperRef) as any).setModalHeight();
  94 + }
  95 + });
  96 + },
87 }; 97 };
  98 +
88 const instance = getCurrentInstance(); 99 const instance = getCurrentInstance();
89 if (instance) { 100 if (instance) {
90 emit('register', modalMethods, instance.uid); 101 emit('register', modalMethods, instance.uid);
@@ -135,6 +146,11 @@ @@ -135,6 +146,11 @@
135 (v) => { 146 (v) => {
136 emit('visible-change', v); 147 emit('visible-change', v);
137 instance && modalMethods.emitVisible?.(v, instance.uid); 148 instance && modalMethods.emitVisible?.(v, instance.uid);
  149 + nextTick(() => {
  150 + if (props.scrollTop && v && unref(modalWrapperRef)) {
  151 + (unref(modalWrapperRef) as any).scrollTop();
  152 + }
  153 + });
138 }, 154 },
139 { 155 {
140 immediate: false, 156 immediate: false,
src/components/Modal/src/components/ModalWrapper.vue
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 55
56 let stopElResizeFn: Fn = () => {}; 56 let stopElResizeFn: Fn = () => {};
57 57
58 - useWindowSizeFn(setModalHeight); 58 + useWindowSizeFn(setModalHeight.bind(null, false));
59 59
60 createModalContext({ 60 createModalContext({
61 redoModalHeight: setModalHeight, 61 redoModalHeight: setModalHeight,
@@ -97,12 +97,21 @@ @@ -97,12 +97,21 @@
97 stopElResizeFn && stopElResizeFn(); 97 stopElResizeFn && stopElResizeFn();
98 }); 98 });
99 99
  100 + async function scrollTop() {
  101 + nextTick(() => {
  102 + const wrapperRefDom = unref(wrapperRef);
  103 + if (!wrapperRefDom) return;
  104 + (wrapperRefDom as any)?.scrollTo?.(0);
  105 + });
  106 + }
  107 +
100 async function setModalHeight() { 108 async function setModalHeight() {
101 // 解决在弹窗关闭的时候监听还存在,导致再次打开弹窗没有高度 109 // 解决在弹窗关闭的时候监听还存在,导致再次打开弹窗没有高度
102 // 加上这个,就必须在使用的时候传递父级的visible 110 // 加上这个,就必须在使用的时候传递父级的visible
103 if (!props.visible) return; 111 if (!props.visible) return;
104 const wrapperRefDom = unref(wrapperRef); 112 const wrapperRefDom = unref(wrapperRef);
105 if (!wrapperRefDom) return; 113 if (!wrapperRefDom) return;
  114 +
106 const bodyDom = wrapperRefDom.$el.parentElement; 115 const bodyDom = wrapperRefDom.$el.parentElement;
107 if (!bodyDom) return; 116 if (!bodyDom) return;
108 bodyDom.style.padding = '0'; 117 bodyDom.style.padding = '0';
@@ -150,7 +159,7 @@ @@ -150,7 +159,7 @@
150 } 159 }
151 } 160 }
152 161
153 - return { wrapperRef, spinRef, spinStyle }; 162 + return { wrapperRef, spinRef, spinStyle, scrollTop, setModalHeight };
154 }, 163 },
155 }); 164 });
156 </script> 165 </script>
src/components/Modal/src/hooks/useModal.ts
@@ -64,10 +64,15 @@ export function useModal(): UseModalReturnType { @@ -64,10 +64,15 @@ export function useModal(): UseModalReturnType {
64 setModalProps: (props: Partial<ModalProps>): void => { 64 setModalProps: (props: Partial<ModalProps>): void => {
65 getInstance()?.setModalProps(props); 65 getInstance()?.setModalProps(props);
66 }, 66 },
  67 +
67 getVisible: computed((): boolean => { 68 getVisible: computed((): boolean => {
68 return visibleData[~~unref(uidRef)]; 69 return visibleData[~~unref(uidRef)];
69 }), 70 }),
70 71
  72 + redoModalHeight: () => {
  73 + getInstance()?.redoModalHeight?.();
  74 + },
  75 +
71 openModal: <T = any>(visible = true, data?: T, openOnSet = true): void => { 76 openModal: <T = any>(visible = true, data?: T, openOnSet = true): void => {
72 getInstance()?.setModalProps({ 77 getInstance()?.setModalProps({
73 visible: visible, 78 visible: visible,
src/components/Modal/src/props.ts
@@ -8,6 +8,7 @@ const { t } = useI18n(); @@ -8,6 +8,7 @@ const { t } = useI18n();
8 8
9 export const modalProps = { 9 export const modalProps = {
10 visible: propTypes.bool, 10 visible: propTypes.bool,
  11 + scrollTop: propTypes.bool.def(true),
11 height: propTypes.number, 12 height: propTypes.number,
12 minHeight: propTypes.number, 13 minHeight: propTypes.number,
13 // open drag 14 // open drag
src/components/Modal/src/types.ts
@@ -6,6 +6,7 @@ import type { CSSProperties, VNodeChild, ComputedRef } from &#39;vue&#39;; @@ -6,6 +6,7 @@ import type { CSSProperties, VNodeChild, ComputedRef } from &#39;vue&#39;;
6 export interface ModalMethods { 6 export interface ModalMethods {
7 setModalProps: (props: Partial<ModalProps>) => void; 7 setModalProps: (props: Partial<ModalProps>) => void;
8 emitVisible?: (visible: boolean, uid: number) => void; 8 emitVisible?: (visible: boolean, uid: number) => void;
  9 + redoModalHeight?: () => void;
9 } 10 }
10 11
11 export type RegisterFn = (modalMethods: ModalMethods, uuid?: string) => void; 12 export type RegisterFn = (modalMethods: ModalMethods, uuid?: string) => void;
@@ -32,6 +33,7 @@ export interface ModalProps { @@ -32,6 +33,7 @@ export interface ModalProps {
32 // 启用wrapper后 底部可以适当增加高度 33 // 启用wrapper后 底部可以适当增加高度
33 wrapperFooterOffset?: number; 34 wrapperFooterOffset?: number;
34 draggable?: boolean; 35 draggable?: boolean;
  36 + scrollTop?: boolean;
35 37
36 // 是否可以进行全屏 38 // 是否可以进行全屏
37 canFullscreen?: boolean; 39 canFullscreen?: boolean;
src/components/Table/src/BasicTable.vue
@@ -205,6 +205,7 @@ @@ -205,6 +205,7 @@
205 if (slots.expandedRowRender) { 205 if (slots.expandedRowRender) {
206 propsData = omit(propsData, 'scroll'); 206 propsData = omit(propsData, 'scroll');
207 } 207 }
  208 +
208 return propsData; 209 return propsData;
209 }); 210 });
210 211
src/views/demo/page/form/high/PersonTable.vue
@@ -98,6 +98,7 @@ @@ -98,6 +98,7 @@
98 dept: '', 98 dept: '',
99 editable: true, 99 editable: true,
100 isNew: true, 100 isNew: true,
  101 + key: `${Date.now()}`,
101 }; 102 };
102 data.push(addRow); 103 data.push(addRow);
103 } 104 }