对话框与系统消息
本教程共 48 篇 · 第 30 篇 · 更新于 2026-08-09 · 约 7 分钟阅读
本节目标:读完你能用前端 JS 调出系统原生的打开文件、保存文件对话框,以及 message / ask / confirm 三种消息框,并知道要在哪里授权。
网页里弹提示通常用 alert()、confirm()。但它们丑、不能定制、而且在某些环境会被浏览器拦截。Tauri 提供了一套系统原生对话框(native dialog):弹出来的窗口是操作系统画的,和你在别的桌面软件里看到的一模一样,风格完全统一。
这套能力来自官方插件 @tauri-apps/plugin-dialog,本章只讲前端怎么用,注册与授权放在后面。
安装并注册 dialog 插件
对话框插件分两端:Rust 端负责真正弹窗,前端 JS 包负责调用。两端都要接。
先在 src-tauri 目录把 Rust 端加进依赖:
cd src-tauri
cargo add tauri-plugin-dialog
然后在 lib.rs 里初始化这个插件:
// src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_dialog::init())
.run(tauri::generate_context!())
.expect("运行 Tauri 应用时出错");
}
前端这边用你习惯的包管理器装 JS 包:
npm install @tauri-apps/plugin-dialog
装好之后,所有对话框函数都从 @tauri-apps/plugin-dialog 导入。下面逐个看。
消息框:message(只给个确定)
message 是最简单的提示框,只有一个「确定」按钮。它适合「告诉你一声」的场景,比如操作成功、出错原因。注意它是异步函数,要 await:
import { message } from "@tauri-apps/plugin-dialog";
// 弹一个错误提示
await message("找不到指定的文件", { title: "提示", kind: "error" });
// 弹一个普通信息
await message("设置已保存", { title: "完成", kind: "info" });
kind 控制图标的类型,可选 info、warning、error,对应信息、警告、错误三种样子。如果用户直接把对话框关掉(点右上角的叉),message 会返回 false,不过大多数场景你并不关心它的返回值。
询问框:ask(是 / 否)
ask 弹出一个带「是 / 否」两个按钮的提问框,返回值是一个布尔值:true 表示点了「是」,false 表示「否」。它适合「确定要删除吗」这类二选一:
import { ask } from "@tauri-apps/plugin-dialog";
const answer = await ask("此操作无法撤销,确定继续吗?", {
title: "确认",
kind: "warning",
});
if (answer) {
console.log("用户选了是,执行删除");
} else {
console.log("用户选了否,取消");
}
Note在 Tauri 2.x 里,
ask与confirm在底层都走message这一条命令通道,官方文档把它们标为message的兼容别名(会在 v3 移除)。日常用ask/confirm名字更直观,授权时只需开dialog:allow-message即可,无需单独为它们配权限。
确认框:confirm(确定 / 取消)
confirm 和 ask 非常像,区别只在按钮文字是「确定 / 取消」而不是「是 / 否」。语义上它更适合「是否执行某个动作」的确认:
import { confirm } from "@tauri-apps/plugin-dialog";
const confirmed = await confirm("是否保存当前修改?", {
title: "保存",
kind: "warning",
});
if (confirmed) {
console.log("用户点了确定");
}
三种消息框的返回都是布尔,写法几乎一致,区别只在按钮文案和语义。
打开文件对话框:open
open 弹出系统的文件选择窗口,让用户挑一个文件或文件夹。它返回选中的路径(字符串),用户取消则返回 null:
import { open } from "@tauri-apps/plugin-dialog";
// 选单个文件
const file = await open({
multiple: false, // 不允许多选
directory: false, // 选文件而不是文件夹
});
if (file) {
console.log("用户选了:", file);
}
想限制可选的文件类型,用 filters 给扩展名过滤;想让用户选多个,把 multiple 设成 true:
const files = await open({
multiple: true,
filters: [
{ name: "图片", extensions: ["png", "jpeg", "jpg"] },
{ name: "全部文件", extensions: ["*"] },
],
});
if (Array.isArray(files)) {
console.log("选了多个文件:", files);
}
directory: true 时对话框切换成「选文件夹」模式。注意:在桌面三系统上 open 返回的是普通文件系统路径;在 Android 上返回的是 content URI,在 iOS 上返回 file:// 开头的 URI——如果你后面要把路径交给「文件系统插件」去读写,那个插件两种格式都能认。
保存文件对话框:save
save 弹出「另存为」窗口,让用户决定文件存到哪、叫什么名字。它返回用户选定的路径,取消则返回 null:
import { save } from "@tauri-apps/plugin-dialog";
const path = await save({
filters: [
{ name: "文本文件", extensions: ["txt", "md"] },
],
});
if (path) {
console.log("将保存到:", path);
// 把这个 path 交给 fs 插件去真正写文件
}
save 只负责「问用户要一个路径」,它不会真的创建或写入文件。真正落盘通常要结合第 32 章讲的「文件系统插件」来完成:先用 save 拿到路径,再调 writeTextFile(path, 内容) 写进去。
capabilities 授权
和菜单一样,对话框插件也要在 capability 里显式授权,否则前端一调用就会被拦下,报「dialog.open not allowed」之类。最简单的方式是开 dialog:default,它已经一次性包含了打开、保存、消息三类权限:
// src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "主窗口的权限",
"windows": ["main"],
"permissions": [
"core:default",
"dialog:default"
]
}
如果你只想开放其中一部分、收紧其它能力,也可以只列具体权限:
{
"permissions": [
"dialog:allow-open",
"dialog:allow-save",
"dialog:allow-message"
]
}
dialog:allow-message 同时覆盖 message / ask / confirm 三种消息框(因为它们共用同一条命令);dialog:allow-open 对应打开对话框,dialog:allow-save 对应保存对话框。按照「最小权限」原则,用到几个就开几个最稳妥。
Tip不确定某个插件到底有哪些权限标识符?在
src-tauri目录跑cargo tauri permission list(或npx tauri permission ls)能列出当前项目所有可用的权限名,照着抄进 capability 就不会错。
小结
对话框插件 @tauri-apps/plugin-dialog 提供两类能力:消息框(message / ask / confirm,返回布尔或 false)和文件对话框(open 选文件、save 选保存位置,返回路径或 null)。它们弹的都是系统原生窗口,风格和本机软件一致。两端都要接:Rust 端 .plugin(tauri_plugin_dialog::init()),前端 npm install @tauri-apps/plugin-dialog。最后别忘了在 capability 里开 dialog:default(或精确到 dialog:allow-*),否则调用会被 security 拦下来。