From a3a903bc86e7248424f94f734d21c86c5327ed20 Mon Sep 17 00:00:00 2001 From: vben Date: Sun, 7 Feb 2021 23:03:59 +0800 Subject: [PATCH] feat(modal): exporse redoModalHeight --- CHANGELOG.zh_CN.md | 4 ++++ src/components/Modal/src/BasicModal.vue | 16 ++++++++++++++++ .../Modal/src/components/ModalWrapper.vue | 13 +++++++++++-- src/components/Modal/src/hooks/useModal.ts | 5 +++++ src/components/Modal/src/props.ts | 1 + src/components/Modal/src/types.ts | 2 ++ src/components/Table/src/BasicTable.vue | 1 + src/views/demo/page/form/high/PersonTable.vue | 1 + 8 files changed, 41 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index e7e6ee4d..cae6939f 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -1,5 +1,9 @@ ## Wip +### ✨ Features + +- useModal 新增返回值函数 `redoModalHeight`,用于在 modal 内为动态内容时刷新 modal 高度 + ### 🐛 Bug Fixes - 修复 Upload 组件 maxNumber 失效问题 diff --git a/src/components/Modal/src/BasicModal.vue b/src/components/Modal/src/BasicModal.vue index 2a68697f..c2dc7fa0 100644 --- a/src/components/Modal/src/BasicModal.vue +++ b/src/components/Modal/src/BasicModal.vue @@ -55,6 +55,7 @@ watchEffect, toRef, getCurrentInstance, + nextTick, } from 'vue'; import Modal from './components/Modal'; @@ -68,6 +69,7 @@ import { basicProps } from './props'; import { useFullScreen } from './hooks/useModalFullScreen'; + import { omit } from 'lodash-es'; export default defineComponent({ name: 'BasicModal', @@ -79,12 +81,21 @@ const visibleRef = ref(false); const propsRef = ref | null>(null); const modalWrapperRef = ref(null); + // modal Bottom and top height const extHeightRef = ref(0); const modalMethods: ModalMethods = { setModalProps, emitVisible: undefined, + redoModalHeight: () => { + nextTick(() => { + if (unref(modalWrapperRef)) { + (unref(modalWrapperRef) as any).setModalHeight(); + } + }); + }, }; + const instance = getCurrentInstance(); if (instance) { emit('register', modalMethods, instance.uid); @@ -135,6 +146,11 @@ (v) => { emit('visible-change', v); instance && modalMethods.emitVisible?.(v, instance.uid); + nextTick(() => { + if (props.scrollTop && v && unref(modalWrapperRef)) { + (unref(modalWrapperRef) as any).scrollTop(); + } + }); }, { immediate: false, diff --git a/src/components/Modal/src/components/ModalWrapper.vue b/src/components/Modal/src/components/ModalWrapper.vue index f456a5c2..8a347adc 100644 --- a/src/components/Modal/src/components/ModalWrapper.vue +++ b/src/components/Modal/src/components/ModalWrapper.vue @@ -55,7 +55,7 @@ let stopElResizeFn: Fn = () => {}; - useWindowSizeFn(setModalHeight); + useWindowSizeFn(setModalHeight.bind(null, false)); createModalContext({ redoModalHeight: setModalHeight, @@ -97,12 +97,21 @@ stopElResizeFn && stopElResizeFn(); }); + async function scrollTop() { + nextTick(() => { + const wrapperRefDom = unref(wrapperRef); + if (!wrapperRefDom) return; + (wrapperRefDom as any)?.scrollTo?.(0); + }); + } + async function setModalHeight() { // 解决在弹窗关闭的时候监听还存在,导致再次打开弹窗没有高度 // 加上这个,就必须在使用的时候传递父级的visible if (!props.visible) return; const wrapperRefDom = unref(wrapperRef); if (!wrapperRefDom) return; + const bodyDom = wrapperRefDom.$el.parentElement; if (!bodyDom) return; bodyDom.style.padding = '0'; @@ -150,7 +159,7 @@ } } - return { wrapperRef, spinRef, spinStyle }; + return { wrapperRef, spinRef, spinStyle, scrollTop, setModalHeight }; }, }); diff --git a/src/components/Modal/src/hooks/useModal.ts b/src/components/Modal/src/hooks/useModal.ts index bd43956d..68309fe0 100644 --- a/src/components/Modal/src/hooks/useModal.ts +++ b/src/components/Modal/src/hooks/useModal.ts @@ -64,10 +64,15 @@ export function useModal(): UseModalReturnType { setModalProps: (props: Partial): void => { getInstance()?.setModalProps(props); }, + getVisible: computed((): boolean => { return visibleData[~~unref(uidRef)]; }), + redoModalHeight: () => { + getInstance()?.redoModalHeight?.(); + }, + openModal: (visible = true, data?: T, openOnSet = true): void => { getInstance()?.setModalProps({ visible: visible, diff --git a/src/components/Modal/src/props.ts b/src/components/Modal/src/props.ts index 1afa4ac6..73103b1c 100644 --- a/src/components/Modal/src/props.ts +++ b/src/components/Modal/src/props.ts @@ -8,6 +8,7 @@ const { t } = useI18n(); export const modalProps = { visible: propTypes.bool, + scrollTop: propTypes.bool.def(true), height: propTypes.number, minHeight: propTypes.number, // open drag diff --git a/src/components/Modal/src/types.ts b/src/components/Modal/src/types.ts index 697fda70..1e31926f 100644 --- a/src/components/Modal/src/types.ts +++ b/src/components/Modal/src/types.ts @@ -6,6 +6,7 @@ import type { CSSProperties, VNodeChild, ComputedRef } from 'vue'; export interface ModalMethods { setModalProps: (props: Partial) => void; emitVisible?: (visible: boolean, uid: number) => void; + redoModalHeight?: () => void; } export type RegisterFn = (modalMethods: ModalMethods, uuid?: string) => void; @@ -32,6 +33,7 @@ export interface ModalProps { // 启用wrapper后 底部可以适当增加高度 wrapperFooterOffset?: number; draggable?: boolean; + scrollTop?: boolean; // 是否可以进行全屏 canFullscreen?: boolean; diff --git a/src/components/Table/src/BasicTable.vue b/src/components/Table/src/BasicTable.vue index c3d663f5..df52e2b1 100644 --- a/src/components/Table/src/BasicTable.vue +++ b/src/components/Table/src/BasicTable.vue @@ -205,6 +205,7 @@ if (slots.expandedRowRender) { propsData = omit(propsData, 'scroll'); } + return propsData; }); diff --git a/src/views/demo/page/form/high/PersonTable.vue b/src/views/demo/page/form/high/PersonTable.vue index 5a796aec..219b68bd 100644 --- a/src/views/demo/page/form/high/PersonTable.vue +++ b/src/views/demo/page/form/high/PersonTable.vue @@ -98,6 +98,7 @@ dept: '', editable: true, isNew: true, + key: `${Date.now()}`, }; data.push(addRow); }