fix: alert beforeClose callback arguments fixed (#5845)

This commit is contained in:
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 IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
export type BeforeCloseScope = {
/** 是否为点击确认按钮触发的关闭 */
isConfirm: boolean;
};
export type AlertProps = { export type AlertProps = {
/** 关闭前的回调如果返回false则终止关闭 */ /** 关闭前的回调如果返回false则终止关闭 */
beforeClose?: () => boolean | Promise<boolean | undefined> | undefined; beforeClose?: (
scope: BeforeCloseScope,
) => boolean | Promise<boolean | undefined> | undefined;
/** 边框 */ /** 边框 */
bordered?: boolean; bordered?: boolean;
/** 取消按钮的标题 */ /** 取消按钮的标题 */
@ -81,7 +88,7 @@ export function alert(
/** /**
* 弹出输入框的函数签名。 * 弹出输入框的函数签名。
* 参数beforeClose会传入用户当前输入的值 * beforeClose的参数会传入用户当前输入的值
* component指定接受用户输入的组件默认为Input * component指定接受用户输入的组件默认为Input
* componentProps 为输入组件设置的属性数据 * componentProps 为输入组件设置的属性数据
* defaultValue 默认的值 * defaultValue 默认的值
@ -90,7 +97,10 @@ export function alert(
export async function prompt<T = any>( export async function prompt<T = any>(
options: Omit<AlertProps, 'beforeClose'> & { options: Omit<AlertProps, 'beforeClose'> & {
beforeClose?: ( beforeClose?: (
val: T, scope: BeforeCloseScope & {
/** 输入组件的当前值 */
value: T;
},
) => boolean | Promise<boolean | undefined> | undefined; ) => boolean | Promise<boolean | undefined> | undefined;
component?: Component; component?: Component;
componentProps?: Recordable<any>; componentProps?: Recordable<any>;

View File

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

View File

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

View File

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

View File

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