Tauri 速查表
快速查阅 Tauri 常用 API 和代码片段。
项目初始化
# 创建新项目
sh <(curl https://create.tauri.app/sh)
# 或使用 npm
npm create tauri-app@latest
# 开发模式运行
npm run tauri dev
# 生产构建
npm run tauri build
配置速查
tauri.conf.json
{
"productName": "My App",
"version": "1.0.0",
"identifier": "com.example.myapp",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:5173",
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build"
},
"app": {
"windows": [{
"title": "My App",
"width": 800,
"height": 600
}]
},
"bundle": {
"active": true,
"targets": ["msi", "dmg", "appimage"]
}
}
权限配置
{
"permissions": [
"core:default",
"fs:allow-read",
"fs:allow-write",
"dialog:allow-open",
"dialog:allow-save",
"notification:default"
]
}
Rust 后端
Command 定义
#[tauri::command]
fn my_command(arg: String) -> Result<String, String> {
Ok(format!("Result: {}", arg))
}
// 异步 Command
#[tauri::command]
async fn async_command() -> Result<String, String> {
tokio::time::sleep(Duration::from_secs(1)).await;
Ok("Done".to_string())
}
// 注册 Commands
.invoke_handler(tauri::generate_handler![my_command, async_command])
访问上下文
// 访问窗口
#[tauri::command]
fn with_window(window: tauri::WebviewWindow) {
window.set_title("New Title").unwrap();
}
// 访问应用句柄
#[tauri::command]
fn with_app(app: tauri::AppHandle) {
let dir = app.path().app_data_dir().unwrap();
}
// 访问状态
#[tauri::command]
fn with_state(state: tauri::State<MyState>) {
let data = state.data.lock().unwrap();
}
事件发送
use tauri::Emitter;
// 发送全局事件
app.emit("event-name", payload).unwrap();
// 发送给特定窗口
app.emit_to("window-label", "event-name", payload).unwrap();
前端 API
调用 Command
import { invoke } from "@tauri-apps/api/core";
// 基础调用
const result = await invoke("command_name", { arg: "value" });
// 带类型
interface Response {
data: string;
}
const result = await invoke<Response>("command_name", {});
// 错误处理
try {
await invoke("risky_command");
} catch (error) {
console.error(error);
}
事件监听
import { listen, emit } from "@tauri-apps/api/event";
// 监听事件
const unlisten = await listen("event-name", (event) => {
console.log(event.payload);
});
// 只监听一次
await once("event-name", (event) => {});
// 发送事件
await emit("event-name", { data: "value" });
// 取消监听
unlisten();
窗口控制
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
const window = getCurrentWebviewWindow();
// 窗口操作
window.minimize();
window.maximize();
window.close();
window.show();
window.hide();
// 设置属性
window.setTitle("New Title");
window.setSize(new LogicalSize(800, 600));
文件系统
import { readTextFile, writeTextFile, BaseDirectory } from "@tauri-apps/api/fs";
// 读取文件
const content = await readTextFile("file.txt", {
baseDir: BaseDirectory.AppData
});
// 写入文件
await writeTextFile("file.txt", "content", {
baseDir: BaseDirectory.AppData
});
对话框
import { open, save, message, confirm } from "@tauri-apps/api/dialog";
// 打开文件
const selected = await open({
filters: [{ name: "Images", extensions: ["png", "jpg"] }]
});
// 保存文件
const path = await save({
defaultPath: "untitled.txt"
});
// 消息框
await message("Hello", { type: "info" });
// 确认框
const yes = await confirm("Are you sure?");
路径
import {
appDataDir,
documentDir,
downloadDir,
join
} from "@tauri-apps/api/path";
const appDir = await appDataDir();
const docDir = await documentDir();
const fullPath = await join(appDir, "config.json");
HTTP 请求
import { fetch } from "@tauri-apps/plugin-http";
const response = await fetch("https://api.example.com/data", {
method: "GET",
headers: { "Content-Type": "application/json" }
});
const data = await response.json();
通知
import {
isPermissionGranted,
requestPermission,
sendNotification
} from "@tauri-apps/plugin-notification";
const permission = await isPermissionGranted();
if (!permission) {
await requestPermission();
}
sendNotification({
title: "Title",
body: "Message body"
});
剪贴板
import { writeText, readText } from "@tauri-apps/plugin-clipboard-manager";
await writeText("text to copy");
const text = await readText();
存储
import { Store } from "@tauri-apps/plugin-store";
const store = new Store("store.bin");
await store.set("key", "value");
const value = await store.get("key");
await store.save();
常用类型
Rust 类型
// 结果类型
Result<T, String>
// 异步结果
async fn command() -> Result<T, String>
// 状态
struct AppState {
data: Mutex<Vec<String>>,
}
TypeScript 类型
// 事件负载
interface EventPayload<T> {
payload: T;
}
// 文件条目
interface FileEntry {
name?: string;
path: string;
children?: FileEntry[];
}
// 窗口大小
interface LogicalSize {
width: number;
height: number;
}
路径占位符
| 占位符 | 说明 |
|---|---|
$APP | 应用数据目录 |
$APPLOG | 应用日志目录 |
$APPCONFIG | 应用配置目录 |
$APPLOCALDATA | 应用本地数据 |
$DOCUMENT | 用户文档目录 |
$DOWNLOAD | 下载目录 |
$HOME | 用户主目录 |
$TEMP | 临时目录 |
快捷键
开发调试
| 快捷键 | 功能 |
|---|---|
Ctrl + Shift + I | 打开 DevTools (Windows/Linux) |
Cmd + Option + I | 打开 DevTools (macOS) |
Ctrl + R | 刷新页面 |
F12 | 打开 DevTools |
全局快捷键
import { register } from "@tauri-apps/plugin-global-shortcut";
await register("CommandOrControl+Shift+C", () => {
console.log("Shortcut triggered");
});
错误处理
Rust
#[tauri::command]
fn safe_command() -> Result<String, String> {
risky_operation()
.map_err(|e| format!("Error: {}", e))
}
TypeScript
try {
await invoke("command");
} catch (error) {
console.error("Command failed:", error);
}
最佳实践速查
安全
- 始终配置权限 Scope
- 验证所有用户输入
- 使用最小权限原则
- 不要在 Events 中传输敏感数据
性能
- 使用异步 Commands 处理 I/O
- 大数据传输使用 Channels
- 及时取消事件监听
- 延迟加载非必要窗口
用户体验
- 显示加载状态
- 处理所有错误情况
- 保存窗口状态
- 提供系统托盘支持