Commit a3a903bc86e7248424f94f734d21c86c5327ed20

Authored by vben
1 parent 33b2365f

feat(modal): exporse redoModalHeight

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