跳到主要内容

消息与通知

命令式反馈辅助函数——轻提示消息(message)、通知(notification)、警告对话框(alert)和确认对话框(confirm)——可以在任何位置调用,包括 React 组件之外。

VEF 专属 API。 这些是从 @vef-framework-react/components 导出的普通函数,而非组件。它们通过 ConfigProvider 注册的 Ant Design App 上下文进行派发,因此渲染出的内容会跟随你的主题、暗色模式和语言设置——这与直接从 antd 导入的静态方法 message.success() / notification.open() 不同。

何时使用

  • 为纯客户端操作(复制、导出、校验)提供反馈,这些场景不在自动 API 反馈的覆盖范围内。
  • 将后台事件——SSE 推送、长任务完成——以可关闭的通知形式呈现。
  • 在非组件代码中(事件处理函数、store action、拦截器)弹出警告或确认对话框来阻断用户操作。

如何选择反馈形式

辅助函数族UI 形式是否打断用户?自动消失典型用途
show*Message屏幕顶部的轻提示是(1.5–4 秒)操作结果、瞬时状态
show*Notification右上角带标题和进度条的卡片是(3–6 秒,duration: 0 可常驻)后台事件、需要标题或操作按钮的内容
show*Alert居中显示、只有一个确定按钮的对话框用户必须知悉的信息
showConfirm居中显示、带确定 / 取消按钮的对话框破坏性或不可逆的操作

声明式场景请优先使用对应组件:页面内嵌横幅使用 Alert,复杂对话框使用 Modal,“先确认再执行”的按钮使用 ActionButton 配合 confirmable

工作原理

<ConfigProvider> 会挂载一个内部的上下文持有器,捕获 antd App.useApp() 的实例(messagenotificationmodal)并存储到 globalThis.$vef 上。辅助函数通过该全局对象读取实例,这意味着:

  • 它们可以在 React 之外工作——axios 拦截器、Zustand action 或普通异步函数中。
  • 它们的输出继承 ConfigProvider 当前的主题、暗色模式和语言设置。
  • <ConfigProvider> 挂载之前调用会抛出 "$vef is not initialized" 错误——切勿在模块顶层调用。

消息(Message)

用于瞬时反馈的轻量级提示。唯一的参数是内容;显示时长按严重程度固定。

import { showSuccessMessage, showErrorMessage, showLoadingMessage } from '@vef-framework-react/components';

async function handleExport() {
const loading = showLoadingMessage('Exporting…');

try {
await exportReport();
showSuccessMessage('Export complete');
} catch {
showErrorMessage('Export failed');
} finally {
loading.close();
}
}
函数签名时长
showSuccessMessage(content: ReactNode) => void1.5 秒
showInfoMessage(content: ReactNode) => void2 秒
showWarningMessage(content: ReactNode) => void3 秒
showErrorMessage(content: ReactNode) => void4 秒
showLoadingMessage(content: ReactNode) => LoadingMessageHandle直到手动关闭
closeAllMessages() => void

showLoadingMessage 返回一个句柄:close() 移除提示,update(content) 在加载动画持续运行的同时替换文案。同时最多显示 3 条消息(由 ConfigProvider 配置)。

通知(Notification)

在右上角渲染的信息更丰富的卡片,带有标题、可选的操作区、倒计时进度条,并支持悬停暂停。打开超过 3 条时会堆叠(最多 8 条)。

import { Button, showInfoNotification } from '@vef-framework-react/components';

const handle = showInfoNotification('A new version is available.', {
title: 'Update',
duration: 0, // 常驻直到手动关闭
actions: <Button size="small" onClick={() => location.reload()}>Reload</Button>,
});

// 稍后,例如事件不再相关时
handle.close();
showSuccessNotification(content: ReactNode, options?: NotificationOptions): NotificationHandle
// showInfoNotification / showWarningNotification / showErrorNotification 签名相同
closeAllNotifications(): void

NotificationOptions

选项类型默认值说明
titleReactNode按严重程度取标签('成功' / '提示' / '警告' / '错误'卡片标题
durationnumber按严重程度为 3 / 4 / 5 / 6自动关闭前的秒数;0 表示常驻
actionsReactNode操作区(按钮、链接)
closablebooleantrue显示关闭按钮
iconReactNode按严重程度取图标自定义图标

警告对话框(Alert)

居中显示、只有一个确定按钮的对话框,用于用户在继续操作前必须知悉的信息。默认隐藏关闭(×)图标,因此点击确定是唯一的退出方式。

import { showErrorAlert } from '@vef-framework-react/components';

showErrorAlert('Your session data could not be restored.', {
title: 'Restore failed',
onOk: () => navigate('/login'),
});
showSuccessAlert(content: ReactNode, options?: AlertOptions): AlertHandle
// showInfoAlert / showWarningAlert / showErrorAlert 签名相同

AlertOptions 即去掉 cancelText / cancelButtonPropsConfirmOptions(没有取消按钮);参见下方表格。Alert 专属默认值:title 回退为严重程度标签,okText'好的,知道了'closablefalse

确认对话框(Confirm)

居中显示的确定 / 取消对话框。当 onOk 返回 Promise 时,确定按钮进入加载状态,Promise resolve 后对话框自动关闭;Promise 被 reject 则保持打开(与 antd Modal.confirm 语义一致)。

import { showConfirm } from '@vef-framework-react/components';

function handleReset() {
showConfirm('This resets all local settings. Continue?', {
title: 'Reset settings',
okText: 'Reset',
okButtonProps: { danger: true },
onOk: async () => {
await resetSettings(); // 确定按钮保持加载状态,直到该 Promise resolve
},
});
}
showConfirm(content: ReactNode, options?: ConfirmOptions): ModalHandle

如果一个按钮的唯一职责就是“先确认再执行”,请优先使用 ActionButton 配合 confirmableconfirmMode="dialog"——它会替你调用 showConfirm 并管理加载状态。

ConfirmOptions

选项类型默认值说明
titleReactNode'确认提示'对话框标题
okTextReactNode语言包默认值确定按钮文案
cancelTextReactNode语言包默认值取消按钮文案(仅 confirm)
okButtonPropsButtonProps确定按钮属性,例如 { danger: true }
cancelButtonPropsButtonProps取消按钮属性(仅 confirm)
widthstring | number对话框宽度
closablebooleantrue(alert 为 false显示关闭(×)图标
onOk() => Awaitable<void>确定回调;异步时确定按钮保持加载
onCancel() => Awaitable<void>取消 / 关闭回调
onAfterOpen() => void打开动画结束后调用
onAfterClose() => void关闭动画结束后调用

所有 alert 和 confirm 对话框都垂直居中显示。

关闭与清理

除“即发即忘”的消息函数外,每个辅助函数都返回一个句柄:

句柄返回自方法
LoadingMessageHandleshowLoadingMessageclose()update(content)
NotificationHandleshow*Notificationclose()update(content, options?)
AlertHandleshow*Alertclose()update(content, options?)
ModalHandleshowConfirmclose()update(content, options?)

update 会替换仍处于打开状态的实例的内容(和选项)——适合在加载消息或常驻通知中汇报进度。需要批量清理时——退出登录、切换工作区——调用 closeAllMessages()closeAllNotifications()

自动 API 反馈

如果你的应用通过 starter 的 createApiClient() 引导启动,请求层已经替你调用了这些辅助函数:

事件自动反馈
请求无法发出错误消息
响应 code ≠ okCode(业务错误)携带服务端 message 的警告消息
HTTP 400警告消息
HTTP 401静默刷新令牌并重试;会话无法恢复时跳转登录页(令牌确已过期时附带一条提示消息)
HTTP 403警告消息,随后进入无权限处理
其他 HTTP 错误(5xx、超时等)错误消息
mutation 成功且结果携带 message 字段成功消息

要为单个 mutation 关闭自动成功提示,在其上设置 meta: { shouldShowSuccessFeedback: false }

只有在这条链路覆盖不到的场景才手动调用辅助函数:纯客户端操作、批量操作后的自定义文案,或将重要失败从轻提示升级为警告对话框。完整链路参见错误处理,背后的 HttpClientOptions 字段参见 HTTP 与 API 客户端

最佳实践

  • 优先依赖自动 API 反馈;不要在每次 API 调用后重复手动弹出提示。
  • 瞬时结果用消息,需要在用户视线离开后仍可查看的内容用通知,只有在用户必须决策或知悉时才使用对话框。
  • 始终在 finally 块中关闭 showLoadingMessage 的句柄,避免失败后残留加载提示。
  • 保留常驻通知(duration: 0)的句柄,在触发场景失效时关闭它;退出登录时调用 closeAllNotifications()
  • 对破坏性操作向 showConfirm 传入 okButtonProps={{ danger: true }};在 React 内部优先使用 ActionButton 配合 confirmable
  • 切勿在模块初始化阶段调用这些辅助函数——必须等 <ConfigProvider> 挂载完成。