系统通知是桌面应用与用户保持连接的重要方式,尤其对于需要后台运行的工具类应用。Tauri 通过 tauri-plugin-notification 插件提供了一套跨平台的原生通知能力,它直接桥接 Windows 的 Toast 通知、macOS 的通知中心以及 Linux 的桌面通知服务,而不是在 WebView 内部模拟。这意味着通知的外观和行为与系统原生应用完全一致,不会有“不和谐”的感觉。
1. 发送桌面通知
在安装并初始化插件后,前端只需调用一个简单的 API:
import { sendNotification } from '@tauri-apps/plugin-notification';
// 一个最简单的通知
sendNotification({
title: '文件已下载',
body: '本次下载共耗时12秒,文件大小3.2MB'
});
通常建议在请求权限之后再发送,但现代系统大多不再强制要求用户手动授权(macOS 在首次发送时会自动提示)。你可以通过 isPermissionGranted() 检查状态,或主动调用 requestPermission() 确保通知能够正常展示。
自定义通知外观
除了标题和正文,你还可以指定图标(仅限本地文件路径或应用资源),部分平台甚至支持大图附件和按钮。
sendNotification({
title: '编译完成',
body: '点击查看详细日志',
icon: 'assets/success.png' // 应用资源路径
});
需要注意的是,Windows 上的图标有尺寸和格式限制(一般推荐 256x256 的 PNG),macOS 则可以复用应用的 Bundle 图标。
2. 通知交互
真正的价值在于用户点击通知后,应用能做出响应。Tauri 的通知 API 返回一个 Promise,当用户点击通知主体时,Promise 会 resolve。你也可以设置 timeout 让通知在一段时间后自动关闭。
// 发送通知并监听用户点击
const response = await sendNotification({
title: '新消息',
body: '来自团队频道的一条未读消息',
timeout: 5000 // 5秒后自动消失
});
if (response === 'clicked') {
// 用户点击了通知,跳转到消息界面
window.show();
navigate('/chat/team');
}
这种模式非常适合触发式的交互:例如下载完成、监控告警、日程提醒等。你无需编写任何 Rust 代码,通知的发送和事件回调完全由前端控制。
其他事件类型
除了 'clicked',部分平台也支持更细粒度的事件:
'dismissed':通知被用户划掉或因超时消失'action':通知上的自定义按钮被点击(需平台支持)
Windows 10/11 的 Toast 通知可以定义按钮,macOS 的通知则需要在设置中开启操作。对于需要复杂交互的场景,建议保持逻辑简单,把核心操作集中在点击事件中处理。
3. 行为回调与 Rust 端处理
如果你的通知操作需要在 Rust 后端执行(比如记录日志、修改配置),可以在前端收到点击事件后,通过 invoke 调用 Rust 命令。
// 在 Rust 中定义一个命令
#[tauri::command]
fn handle_notification_click(source: String) {
println!("用户点击了来自 {} 的通知", source);
// 执行后续操作,如打开文件夹、启动任务等
}
// 前端捕获点击并调用后端
const action = await sendNotification({ title: '任务完成', body: '点击打开文件夹' });
if (action === 'clicked') {
invoke('handle_notification_click', { source: 'download' });
}
这样一来,通知的生命周期完全由你控制:前端负责展示和用户交互,Rust 负责执行系统级的响应操作。
4. 实用建议
- 静默模式下评估必要性:Windows 的 Focus Assist 或 macOS 的勿扰模式下,通知可能被系统隐藏。对于关键提醒,考虑结合系统托盘闪烁或声音提示。
- 避免滥用:连续弹出一堆通知会惹恼用户,也容易被系统自动禁用。建议提供“关闭通知”的设置项。
- 图标资源:统一使用一套高清图标,避免在不同 DPI 屏幕下模糊。可以将图标文件放在
icons/目录下并通过配置注册为应用资源。
系统通知在 Tauri 中实现起来非常简洁,十分钟内即可完成集成。把它作为用户体验的一个锦上添花的组件,能让你的桌面应用真正具备“原生感”。