Tauri后端消息无法发送:窗口加载时事件接收失败
解决Tauri前端无法接收后端"loaded"事件的问题
你的核心问题是后端发送事件的时机过早:在setup阶段执行emit_all时,前端WebView还未完成加载,React的useEffect还没注册监听,导致事件被错过。
修复方案
方案1:后端等待WebView就绪后发送事件
修改main.rs,在WebView完全加载后再发送"loaded"事件:
use serde::Serialize; // 必须实现Serialize才能将数据序列化为JSON发送给前端 #[derive(Serialize)] struct Payload { message: String, } fn main() { tauri::Builder::default() .setup(|app| { // 获取主窗口(默认窗口标识为"main",需与tauri.conf.json一致) let main_window = app.get_window("main").expect("Failed to get main window"); // 监听WebView加载完成事件,此时前端已准备好接收消息 main_window.on_webview_ready(move |window| { window.emit("loaded", Payload { message: "Tauri is awesome!".into() }).unwrap(); }); Ok(()) }) .invoke_handler(tauri::generate_handler![]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
方案2:前端主动请求初始化数据(更可靠的替代方案)
如果需要更灵活的控制,可让前端在加载完成后主动调用后端接口获取数据:
前端App.tsx代码:
React.useEffect(() => { // 页面加载完成后主动调用后端接口 invoke("fetch_initial_data") .then((payload) => { console.log(payload); readFileContents(); }) .catch(err => console.error("Failed to fetch data:", err)); }, []);
后端main.rs代码:
use serde::Serialize; use tauri::command; #[derive(Serialize)] struct Payload { message: String, } // 定义后端命令,供前端调用 #[command] fn fetch_initial_data() -> Payload { Payload { message: "Tauri is awesome!".into() } } fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![fetch_initial_data]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
关键注意点
- 确保
Payload结构体实现serde::Serializetrait,否则无法完成JSON序列化。 - 检查
tauri.conf.json中的窗口名称是否与get_window的参数匹配(默认是"main")。
内容的提问来源于stack exchange,提问作者Jens L
相关产品推荐
相关产品推荐

