mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-02-02 18:28:40 +08:00
feat: drawer support onOpened
& onClosed
This commit is contained in:
parent
4a8e6abc06
commit
e86a7906fe
@ -108,12 +108,14 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
|||||||
|
|
||||||
以下事件,只有在 `useVbenDrawer({onCancel:()=>{}})` 中传入才会生效。
|
以下事件,只有在 `useVbenDrawer({onCancel:()=>{}})` 中传入才会生效。
|
||||||
|
|
||||||
| 事件名 | 描述 | 类型 |
|
| 事件名 | 描述 | 类型 | 版本限制 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` |
|
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` | --- |
|
||||||
| onCancel | 点击取消按钮触发 | `()=>void` |
|
| onCancel | 点击取消按钮触发 | `()=>void` | --- |
|
||||||
| onConfirm | 点击确认按钮触发 | `()=>void` |
|
| onClosed | 关闭动画播放完毕时触发 | `()=>void` | >5.5.2 |
|
||||||
| onOpenChange | 关闭或者打开弹窗时触发 | `(isOpen:boolean)=>void` |
|
| onConfirm | 点击确认按钮触发 | `()=>void` | --- |
|
||||||
|
| onOpenChange | 关闭或者打开弹窗时触发 | `(isOpen:boolean)=>void` | --- |
|
||||||
|
| onOpened | 打开动画播放完毕时触发 | `()=>void` | >5.5.2 |
|
||||||
|
|
||||||
### Slots
|
### Slots
|
||||||
|
|
||||||
|
@ -110,4 +110,19 @@ describe('drawerApi', () => {
|
|||||||
expect(drawerApi.store.state.title).toBe('Batch Title');
|
expect(drawerApi.store.state.title).toBe('Batch Title');
|
||||||
expect(drawerApi.store.state.confirmText).toBe('Batch Confirm');
|
expect(drawerApi.store.state.confirmText).toBe('Batch Confirm');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should call onClosed callback when provided', () => {
|
||||||
|
const onClosed = vi.fn();
|
||||||
|
const drawerApiWithHook = new DrawerApi({ onClosed });
|
||||||
|
drawerApiWithHook.onClosed();
|
||||||
|
expect(onClosed).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call onOpened callback when provided', () => {
|
||||||
|
const onOpened = vi.fn();
|
||||||
|
const drawerApiWithHook = new DrawerApi({ onOpened });
|
||||||
|
drawerApiWithHook.open();
|
||||||
|
drawerApiWithHook.onOpened();
|
||||||
|
expect(onOpened).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,12 @@ import { bindMethods, isFunction } from '@vben-core/shared/utils';
|
|||||||
export class DrawerApi {
|
export class DrawerApi {
|
||||||
private api: Pick<
|
private api: Pick<
|
||||||
DrawerApiOptions,
|
DrawerApiOptions,
|
||||||
'onBeforeClose' | 'onCancel' | 'onConfirm' | 'onOpenChange'
|
| 'onBeforeClose'
|
||||||
|
| 'onCancel'
|
||||||
|
| 'onClosed'
|
||||||
|
| 'onConfirm'
|
||||||
|
| 'onOpenChange'
|
||||||
|
| 'onOpened'
|
||||||
>;
|
>;
|
||||||
// private prevState!: DrawerState;
|
// private prevState!: DrawerState;
|
||||||
private state!: DrawerState;
|
private state!: DrawerState;
|
||||||
@ -23,8 +28,10 @@ export class DrawerApi {
|
|||||||
connectedComponent: _,
|
connectedComponent: _,
|
||||||
onBeforeClose,
|
onBeforeClose,
|
||||||
onCancel,
|
onCancel,
|
||||||
|
onClosed,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
|
onOpened,
|
||||||
...storeState
|
...storeState
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
@ -68,8 +75,10 @@ export class DrawerApi {
|
|||||||
this.api = {
|
this.api = {
|
||||||
onBeforeClose,
|
onBeforeClose,
|
||||||
onCancel,
|
onCancel,
|
||||||
|
onClosed,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
|
onOpened,
|
||||||
};
|
};
|
||||||
bindMethods(this);
|
bindMethods(this);
|
||||||
}
|
}
|
||||||
@ -106,6 +115,15 @@ export class DrawerApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹窗关闭动画播放完毕后的回调
|
||||||
|
*/
|
||||||
|
onClosed() {
|
||||||
|
if (!this.state.isOpen) {
|
||||||
|
this.api.onClosed?.();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确认操作
|
* 确认操作
|
||||||
*/
|
*/
|
||||||
@ -113,6 +131,15 @@ export class DrawerApi {
|
|||||||
this.api.onConfirm?.();
|
this.api.onConfirm?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹窗打开动画播放完毕后的回调
|
||||||
|
*/
|
||||||
|
onOpened() {
|
||||||
|
if (this.state.isOpen) {
|
||||||
|
this.api.onOpened?.();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
this.store.setState((prev) => ({ ...prev, isOpen: true }));
|
this.store.setState((prev) => ({ ...prev, isOpen: true }));
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,11 @@ export interface DrawerApiOptions extends DrawerState {
|
|||||||
* 点击取消按钮的回调
|
* 点击取消按钮的回调
|
||||||
*/
|
*/
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
|
/**
|
||||||
|
* 弹窗关闭动画结束的回调
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
onClosed?: () => void;
|
||||||
/**
|
/**
|
||||||
* 点击确定按钮的回调
|
* 点击确定按钮的回调
|
||||||
*/
|
*/
|
||||||
@ -148,4 +153,9 @@ export interface DrawerApiOptions extends DrawerState {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
onOpenChange?: (isOpen: boolean) => void;
|
onOpenChange?: (isOpen: boolean) => void;
|
||||||
|
/**
|
||||||
|
* 弹窗打开动画结束的回调
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
onOpened?: () => void;
|
||||||
}
|
}
|
||||||
|
@ -139,10 +139,12 @@ const getAppendTo = computed(() => {
|
|||||||
:side="placement"
|
:side="placement"
|
||||||
:z-index="zIndex"
|
:z-index="zIndex"
|
||||||
@close-auto-focus="handleFocusOutside"
|
@close-auto-focus="handleFocusOutside"
|
||||||
|
@closed="() => drawerApi?.onClosed()"
|
||||||
@escape-key-down="escapeKeyDown"
|
@escape-key-down="escapeKeyDown"
|
||||||
@focus-outside="handleFocusOutside"
|
@focus-outside="handleFocusOutside"
|
||||||
@interact-outside="interactOutside"
|
@interact-outside="interactOutside"
|
||||||
@open-auto-focus="handerOpenAutoFocus"
|
@open-auto-focus="handerOpenAutoFocus"
|
||||||
|
@opened="() => drawerApi?.onOpened()"
|
||||||
@pointer-down-outside="pointerDownOutside"
|
@pointer-down-outside="pointerDownOutside"
|
||||||
>
|
>
|
||||||
<SheetHeader
|
<SheetHeader
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
import { cn } from '@vben-core/shared/utils';
|
import { cn } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
@ -32,7 +32,9 @@ const props = withDefaults(defineProps<SheetContentProps>(), {
|
|||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits<DialogContentEmits>();
|
const emits = defineEmits<
|
||||||
|
{ close: []; closed: []; opened: [] } & DialogContentEmits
|
||||||
|
>();
|
||||||
|
|
||||||
const delegatedProps = computed(() => {
|
const delegatedProps = computed(() => {
|
||||||
const {
|
const {
|
||||||
@ -59,6 +61,17 @@ const position = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||||
|
const contentRef = ref<InstanceType<typeof DialogContent> | null>(null);
|
||||||
|
function onAnimationEnd(event: AnimationEvent) {
|
||||||
|
// 只有在 contentRef 的动画结束时才触发 opened/closed 事件
|
||||||
|
if (event.target === contentRef.value?.$el) {
|
||||||
|
if (props.open) {
|
||||||
|
emits('opened');
|
||||||
|
} else {
|
||||||
|
emits('closed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -67,8 +80,10 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||||||
<SheetOverlay v-if="open && modal" :style="{ zIndex, position }" />
|
<SheetOverlay v-if="open && modal" :style="{ zIndex, position }" />
|
||||||
</Transition>
|
</Transition>
|
||||||
<DialogContent
|
<DialogContent
|
||||||
|
ref="contentRef"
|
||||||
:class="cn(sheetVariants({ side }), props.class)"
|
:class="cn(sheetVariants({ side }), props.class)"
|
||||||
:style="{ zIndex, position }"
|
:style="{ zIndex, position }"
|
||||||
|
@animationend="onAnimationEnd"
|
||||||
v-bind="{ ...forwarded, ...$attrs }"
|
v-bind="{ ...forwarded, ...$attrs }"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
Loading…
Reference in New Issue
Block a user