perf: improve destroyOnClose for VbenDrawer&VbenModal (#6051)
* fix: fix that the default value of modal destroyOnClose does not take effect * perf: improve destroyOnClose for VbenDrawer
This commit is contained in:
parent
0a9fc4e02d
commit
0cc1cb5a7b
@ -52,6 +52,10 @@ export interface DrawerProps {
|
|||||||
* 弹窗描述
|
* 弹窗描述
|
||||||
*/
|
*/
|
||||||
description?: string;
|
description?: string;
|
||||||
|
/**
|
||||||
|
* 在关闭时销毁抽屉
|
||||||
|
*/
|
||||||
|
destroyOnClose?: boolean;
|
||||||
/**
|
/**
|
||||||
* 是否显示底部
|
* 是否显示底部
|
||||||
* @default true
|
* @default true
|
||||||
@ -143,10 +147,6 @@ export interface DrawerApiOptions extends DrawerState {
|
|||||||
* 独立的抽屉组件
|
* 独立的抽屉组件
|
||||||
*/
|
*/
|
||||||
connectedComponent?: Component;
|
connectedComponent?: Component;
|
||||||
/**
|
|
||||||
* 在关闭时销毁抽屉。仅在使用 connectedComponent 时有效
|
|
||||||
*/
|
|
||||||
destroyOnClose?: boolean;
|
|
||||||
/**
|
/**
|
||||||
* 关闭前的回调,返回 false 可以阻止关闭
|
* 关闭前的回调,返回 false 可以阻止关闭
|
||||||
* @returns
|
* @returns
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { DrawerProps, ExtendedDrawerApi } from './drawer';
|
import type { DrawerProps, ExtendedDrawerApi } from './drawer';
|
||||||
|
|
||||||
import { computed, provide, ref, useId, watch } from 'vue';
|
import { computed, provide, ref, unref, useId, watch } from 'vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useIsMobile,
|
useIsMobile,
|
||||||
@ -35,6 +35,7 @@ interface Props extends DrawerProps {
|
|||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
appendToMain: false,
|
appendToMain: false,
|
||||||
closeIconPlacement: 'right',
|
closeIconPlacement: 'right',
|
||||||
|
destroyOnClose: true,
|
||||||
drawerApi: undefined,
|
drawerApi: undefined,
|
||||||
submitting: false,
|
submitting: false,
|
||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
@ -63,6 +64,7 @@ const {
|
|||||||
confirmText,
|
confirmText,
|
||||||
contentClass,
|
contentClass,
|
||||||
description,
|
description,
|
||||||
|
destroyOnClose,
|
||||||
footer: showFooter,
|
footer: showFooter,
|
||||||
footerClass,
|
footerClass,
|
||||||
header: showHeader,
|
header: showHeader,
|
||||||
@ -131,6 +133,29 @@ const getAppendTo = computed(() => {
|
|||||||
? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
|
? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
|
||||||
: undefined;
|
: undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destroyOnClose功能完善
|
||||||
|
*/
|
||||||
|
// 是否打开过
|
||||||
|
const hasOpened = ref(false);
|
||||||
|
const isClosed = ref(true);
|
||||||
|
watch(
|
||||||
|
() => state?.value?.isOpen,
|
||||||
|
(value) => {
|
||||||
|
isClosed.value = false;
|
||||||
|
if (value && !unref(hasOpened)) {
|
||||||
|
hasOpened.value = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
function handleClosed() {
|
||||||
|
isClosed.value = true;
|
||||||
|
props.drawerApi?.onClosed();
|
||||||
|
}
|
||||||
|
const getForceMount = computed(() => {
|
||||||
|
return !unref(destroyOnClose) && unref(hasOpened);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Sheet
|
<Sheet
|
||||||
@ -144,15 +169,17 @@ const getAppendTo = computed(() => {
|
|||||||
cn('flex w-[520px] flex-col', drawerClass, {
|
cn('flex w-[520px] flex-col', drawerClass, {
|
||||||
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
|
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
|
||||||
'max-h-[100vh]': placement === 'bottom' || placement === 'top',
|
'max-h-[100vh]': placement === 'bottom' || placement === 'top',
|
||||||
|
hidden: isClosed,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
:modal="modal"
|
:modal="modal"
|
||||||
:open="state?.isOpen"
|
:open="state?.isOpen"
|
||||||
:side="placement"
|
:side="placement"
|
||||||
:z-index="zIndex"
|
:z-index="zIndex"
|
||||||
|
:force-mount="getForceMount"
|
||||||
:overlay-blur="overlayBlur"
|
:overlay-blur="overlayBlur"
|
||||||
@close-auto-focus="handleFocusOutside"
|
@close-auto-focus="handleFocusOutside"
|
||||||
@closed="() => drawerApi?.onClosed()"
|
@closed="handleClosed"
|
||||||
@escape-key-down="escapeKeyDown"
|
@escape-key-down="escapeKeyDown"
|
||||||
@focus-outside="handleFocusOutside"
|
@focus-outside="handleFocusOutside"
|
||||||
@interact-outside="interactOutside"
|
@interact-outside="interactOutside"
|
||||||
|
@ -21,7 +21,9 @@ import VbenDrawer from './drawer.vue';
|
|||||||
|
|
||||||
const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT');
|
const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT');
|
||||||
|
|
||||||
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {};
|
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {
|
||||||
|
destroyOnClose: true,
|
||||||
|
};
|
||||||
|
|
||||||
export function setDefaultDrawerProps(props: Partial<DrawerProps>) {
|
export function setDefaultDrawerProps(props: Partial<DrawerProps>) {
|
||||||
Object.assign(DEFAULT_DRAWER_PROPS, props);
|
Object.assign(DEFAULT_DRAWER_PROPS, props);
|
||||||
|
@ -17,7 +17,9 @@ import VbenModal from './modal.vue';
|
|||||||
|
|
||||||
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
|
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
|
||||||
|
|
||||||
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {};
|
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {
|
||||||
|
destroyOnClose: true,
|
||||||
|
};
|
||||||
|
|
||||||
export function setDefaultModalProps(props: Partial<ModalProps>) {
|
export function setDefaultModalProps(props: Partial<ModalProps>) {
|
||||||
Object.assign(DEFAULT_MODAL_PROPS, props);
|
Object.assign(DEFAULT_MODAL_PROPS, props);
|
||||||
@ -86,7 +88,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
|
|||||||
|
|
||||||
mergedOptions.onClosed = () => {
|
mergedOptions.onClosed = () => {
|
||||||
options.onClosed?.();
|
options.onClosed?.();
|
||||||
if (options.destroyOnClose) {
|
if (mergedOptions.destroyOnClose) {
|
||||||
injectData.reCreateModal?.();
|
injectData.reCreateModal?.();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -5,9 +5,27 @@ import { useVbenDrawer } from '@vben/common-ui';
|
|||||||
|
|
||||||
import { Input, message } from 'ant-design-vue';
|
import { Input, message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
|
||||||
const value = ref('');
|
const value = ref('');
|
||||||
|
|
||||||
|
const [Form] = useVbenForm({
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'KeepAlive测试:内部组件',
|
||||||
|
},
|
||||||
|
fieldName: 'field1',
|
||||||
|
hideLabel: true,
|
||||||
|
label: '字段1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
showDefaultActions: false,
|
||||||
|
});
|
||||||
|
|
||||||
const [Drawer, drawerApi] = useVbenDrawer({
|
const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
|
destroyOnClose: false,
|
||||||
onCancel() {
|
onCancel() {
|
||||||
drawerApi.close();
|
drawerApi.close();
|
||||||
},
|
},
|
||||||
@ -20,7 +38,11 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
|||||||
<template>
|
<template>
|
||||||
<Drawer append-to-main title="基础抽屉示例" title-tooltip="标题提示内容">
|
<Drawer append-to-main title="基础抽屉示例" title-tooltip="标题提示内容">
|
||||||
<template #extra> extra </template>
|
<template #extra> extra </template>
|
||||||
本抽屉指定在内容区域打开
|
此弹窗指定在内容区域打开,并且在关闭之后弹窗内容不会被销毁
|
||||||
<Input v-model="value" placeholder="KeepAlive测试" />
|
<Input
|
||||||
|
v-model:value="value"
|
||||||
|
placeholder="KeepAlive测试:connectedComponent"
|
||||||
|
/>
|
||||||
|
<Form />
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user