在 Tauri 应用中,生命周期钩子让你能在应用启动、窗口创建和退出等关键节点执行自定义逻辑,例如初始化配置、打开调试工具或清理资源。这些钩子都在 Rust 端通过 tauri::Builder 提供的方法进行注册,写法简洁且可靠。
启动钩子:setup
应用核心初始化完成后、前端页面加载之前触发。这是做一次性准备工作最合适的时机:
- 读取本地配置文件
- 初始化日志系统
- 启动后台服务(如本地服务器、守护线程)
- 预加载数据到状态管理
示例:
fn main() {
tauri::Builder::default()
.setup(|app| {
// 这里可以访问 app 实例,管理状态、注册资源
println!("应用启动,执行初始化任务");
Ok(())
})
.run(tauri::generate_context!())
.expect("启动失败");
}
注意:setup 闭包必须返回 Ok(()),否则应用会终止启动。它运行在 Rust 的异步上下文中,但本身是同步的;如果需要异步初始化,可以使用 tauri::async_runtime::spawn 另行安排。
窗口创建钩子:on_window_event 与 on_page_load
Tauri 没有直接的“窗口创建时”全局钩子,但可以通过窗口的事件监听实现。创建窗口后,可以在 setup 阶段拿到窗口实例并监听其事件,或者使用 tauri::WindowBuilder 的 on_navigation 等。
on_window_event:监听窗口大小变化、聚焦、关闭请求等。可以在窗口首次Resized或Focused时执行逻辑,模拟窗口创建完成。on_page_load:WebviewBuilder提供的事件,当 WebView 开始加载或加载完成时触发,适合注入初始脚本或显示加载动画。
示例(在 setup 中获取已有窗口并监听):
.setup(|app| {
let window = app.get_window("main").unwrap();
window.on_window_event(|event| {
if let tauri::WindowEvent::Focused(focused) = event {
if *focused {
// 窗口获得焦点,可视为用户可见后的首次交互准备
}
}
});
Ok(())
})
更常见的做法是在创建窗口时直接用 WindowBuilder 指定事件:
tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into()))
.on_page_load(|window, _| {
// 页面加载完成,DOM 就绪
})
.build()?;
退出钩子:on_exit(或直接使用 Rust 的 Drop)
Tauri 提供了 on_exit 方法来注册一个在应用完全退出前执行的函数,适合做清理工作:
- 保存用户界面状态(窗口位置、尺寸)
- 关闭数据库连接、停止后台进程
- 写入日志尾部信息
- 清理临时文件
示例:
fn main() {
tauri::Builder::default()
.on_exit(|_app_handle| {
println!("应用即将退出,执行清理");
// 这里 _app_handle 无法保证完全可用(资源可能已释放),仅做轻量级操作
})
.run(tauri::generate_context!())
.expect("启动失败");
}
重要说明:on_exit 是同步的,且调用时 Tauri 运行时可能已部分销毁,不能依赖窗口或状态管理器。如需更可靠的资源释放,应利用 Rust 的 Drop 特性管理自定义结构体,或使用 setup 中注册的全局资源。
此外,窗口关闭事件(close_requested)允许你阻止关闭或弹出确认对话框:
window.on_window_event(|event| {
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
api.prevent_close();
// 显示确认对话框,然后手动关闭窗口
}
});
通过这三个核心钩子,你可以精确控制应用从生到死的完整流程,代码量少且逻辑清晰,没有 Electron 中多个进程事件交织的复杂情况。