fix: alert `beforeClose` callback arguments fixed (#5845)

pull/78/MERGE
Netfan 2025-04-01 22:55:29 +08:00 committed by GitHub
parent 1d9f1be004
commit ecf518bb02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 43 additions and 21 deletions

View File

@ -38,9 +38,16 @@ Alert提供的功能与Modal类似但只适用于简单应用场景。例如
/** 预置的图标类型 */
export type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
export type BeforeCloseScope = {
/** 是否为点击确认按钮触发的关闭 */
isConfirm: boolean;
};
export type AlertProps = {
/** 关闭前的回调如果返回false则终止关闭 */
beforeClose?: () => boolean | Promise<boolean | undefined> | undefined;
beforeClose?: (
scope: BeforeCloseScope,
) => boolean | Promise<boolean | undefined> | undefined;
/** 边框 */
bordered?: boolean;
/** 取消按钮的标题 */
@ -81,7 +88,7 @@ export function alert(
/**
* 弹出输入框的函数签名。
* 参数beforeClose会传入用户当前输入的值
* beforeClose的参数会传入用户当前输入的值
* component指定接受用户输入的组件默认为Input
* componentProps 为输入组件设置的属性数据
* defaultValue 默认的值
@ -90,7 +97,10 @@ export function alert(
export async function prompt<T = any>(
options: Omit<AlertProps, 'beforeClose'> & {
beforeClose?: (
val: T,
scope: BeforeCloseScope & {
/** 输入组件的当前值 */
value: T;
},
) => boolean | Promise<boolean | undefined> | undefined;
component?: Component;
componentProps?: Recordable<any>;

View File

@ -2,7 +2,7 @@ import type { Component } from 'vue';
import type { Recordable } from '@vben-core/typings';
import type { AlertProps } from './alert';
import type { AlertProps, BeforeCloseScope } from './alert';
import { h, ref, render } from 'vue';
@ -131,9 +131,10 @@ export function vbenConfirm(
export async function vbenPrompt<T = any>(
options: Omit<AlertProps, 'beforeClose'> & {
beforeClose?: (
val: T,
) => boolean | Promise<boolean | undefined> | undefined;
beforeClose?: (scope: {
isConfirm: boolean;
value: T | undefined;
}) => boolean | Promise<boolean | undefined> | undefined;
component?: Component;
componentProps?: Recordable<any>;
defaultValue?: T;
@ -165,9 +166,12 @@ export async function vbenPrompt<T = any>(
contents.push(componentRef);
const props: AlertProps & Recordable<any> = {
...delegated,
async beforeClose() {
async beforeClose(scope: BeforeCloseScope) {
if (delegated.beforeClose) {
return await delegated.beforeClose(modelValue.value);
return await delegated.beforeClose({
...scope,
value: modelValue.value,
});
}
},
content: h(

View File

@ -2,9 +2,15 @@ import type { Component } from 'vue';
export type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
export type BeforeCloseScope = {
isConfirm: boolean;
};
export type AlertProps = {
/** 关闭前的回调如果返回false则终止关闭 */
beforeClose?: () => boolean | Promise<boolean | undefined> | undefined;
beforeClose?: (
scope: BeforeCloseScope,
) => boolean | Promise<boolean | undefined> | undefined;
/** 边框 */
bordered?: boolean;
/** 取消按钮的标题 */

View File

@ -92,15 +92,17 @@ function handleConfirm() {
isConfirm.value = true;
emits('confirm');
}
function handleCancel() {
open.value = false;
isConfirm.value = false;
}
const loading = ref(false);
async function handleOpenChange(val: boolean) {
if (!val && props.beforeClose) {
loading.value = true;
try {
const res = await props.beforeClose();
const res = await props.beforeClose({ isConfirm: isConfirm.value });
if (res !== false) {
open.value = false;
}
@ -141,6 +143,7 @@ async function handleOpenChange(val: boolean) {
size="icon"
class="rounded-full"
:disabled="loading"
@click="handleCancel"
>
<X class="text-muted-foreground size-4" />
</VbenButton>
@ -154,22 +157,20 @@ async function handleOpenChange(val: boolean) {
<VbenLoading v-if="loading" :spinning="loading" />
</AlertDialogDescription>
<div class="flex justify-end gap-x-2">
<AlertDialogCancel
v-if="showCancel"
@click="handleCancel"
:disabled="loading"
>
<AlertDialogCancel v-if="showCancel" :disabled="loading">
<component
:is="components.DefaultButton || VbenButton"
variant="ghost"
@click="handleCancel"
>
{{ cancelText || $t('cancel') }}
</component>
</AlertDialogCancel>
<AlertDialogAction @click="handleConfirm">
<AlertDialogAction>
<component
:is="components.PrimaryButton || VbenButton"
:loading="loading"
@click="handleConfirm"
>
{{ confirmText || $t('confirm') }}
</component>

View File

@ -129,7 +129,8 @@ onBeforeUnmount(() => {
function openConfirm() {
confirm({
beforeClose() {
beforeClose({ isConfirm }) {
if (!isConfirm) return;
//
return new Promise((resolve) => {
setTimeout(() => {
@ -150,8 +151,8 @@ function openConfirm() {
async function openPrompt() {
prompt<string>({
async beforeClose(val) {
if (val === '芝士') {
async beforeClose({ isConfirm, value }) {
if (isConfirm && value === '芝士') {
message.error('不能吃芝士');
return false;
}