如何从Yew前端通过Tauri调用tauri_plugin_store存储表单数据?
问题描述
我有一个Tauri后端+Yew前端的项目,想用tauri_plugin_store把表单数据保存到文件,但相关文档不够完善。目前能从Yew的form.rs调用Tauri的save_to_file命令并传递参数,但store是main函数setup里的局部变量,没法在save_to_file中调用它完成存储。
Tauri的main.rs代码
// Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use tauri::Error; use tauri_plugin_store::StoreBuilder; use serde_json::json; // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command #[tauri::command] fn greets(name: &str) -> String { format!("Hello, {}! You've been greeted from Rust!", name) } #[tauri::command] fn save_to_file(day: &str, text: &str, parent: &str) -> Result<(), Error>{ println!(">>>>{}", text); return Ok(()) } fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greets, save_to_file]) .plugin(tauri_plugin_store::Builder::default().build()) .setup(|app| { let mut store = StoreBuilder::new(app.handle(), "/Users/a/Desktop/tauri_project/store.bin".parse()?).build(); Ok(store.insert("a".to_string(), json!("b"))?) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
Yew的form.rs调用代码
fn execute_effect(user_record: Record) { spawn_local(async move { if user_record.day == "" || user_record.text == "" || user_record.parent == "" { return; } else { let args = to_value(&Record { day: user_record.day.clone(), text: user_record.text.clone(), parent: user_record.parent.clone(), }) .unwrap(); let new_msg = invoke("save_to_file", args).await.as_string(); log!("{:#?}", new_msg); } }); }
我在GitHub上看到这段示例代码,但不清楚StoreCollection是什么、如何在Yew中导入tauri以及app指代的内容,求解决方法:
//As you may have noticed, the Store crated above isn't accessible to the frontend. To interoperate with stores created by JS use the exported with_store method: use tauri::Wry; use tauri_plugin_store::with_store; let stores = app.state::<StoreCollection<Wry>>(); let path = PathBuf::from("path/to/the/storefile"); with_store(app_handle, stores, path, |store| store.insert("a".to_string(), json!("b")))
解决方案
1. 核心概念说明
StoreCollection:tauri_plugin_store提供的全局存储集合,注册插件时会自动注入到Tauri应用状态中,用来统一管理所有Store实例。AppHandle:Tauri应用的核心句柄,可通过命令参数注入,用于访问应用状态、资源等。
2. 修改Tauri端main.rs代码
调整save_to_file命令,通过全局StoreCollection获取并操作Store:
// Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use tauri::{Error, AppHandle, Wry}; use tauri_plugin_store::{StoreBuilder, StoreCollection, with_store}; use serde_json::json; use std::path::PathBuf; #[tauri::command] fn greets(name: &str) -> String { format!("Hello, {}! You've been greeted from Rust!", name) } #[tauri::command] async fn save_to_file(app_handle: AppHandle, day: &str, text: &str, parent: &str) -> Result<(), Error>{ // 与setup中一致的Store文件路径 let store_path = PathBuf::from("/Users/a/Desktop/tauri_project/store.bin"); // 获取全局的StoreCollection实例 let stores = app_handle.state::<StoreCollection<Wry>>(); // 操作指定路径的Store with_store(app_handle.clone(), stores, store_path, |store| { // 组织表单数据为JSON格式 let record = json!({ "day": day, "text": text, "parent": parent }); // 生成唯一键(可根据业务调整) let key = format!("{}_{}", day, parent); // 插入数据到Store store.insert(key, record)?; // 手动持久化到文件(Store不会自动保存) store.save()?; Ok(()) })?; println!("数据保存成功: {}", text); Ok(()) } fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greets, save_to_file]) .plugin(tauri_plugin_store::Builder::default().build()) .setup(|app| { let mut store = StoreBuilder::new(app.handle(), "/Users/a/Desktop/tauri_project/store.bin".parse()?).build(); // 初始化测试数据 store.insert("a".to_string(), json!("b"))?; // 初始化后保存到文件 store.save()?; Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
3. Yew端代码调整
确保调用参数与命令定义匹配,简化参数传递逻辑:
fn execute_effect(user_record: Record) { spawn_local(async move { if user_record.day.is_empty() || user_record.text.is_empty() || user_record.parent.is_empty() { return; } // 直接传递三个参数,与命令定义对齐 let result = invoke("save_to_file", (user_record.day, user_record.text, user_record.parent)).await; match result { Ok(_) => log!("数据保存成功"), Err(e) => log!("保存失败: {:#?}", e), } }); }
额外说明
- Yew中导入Tauri:在项目
Cargo.toml中添加依赖tauri = { version = "1.x", features = ["api"] },然后在代码中use tauri::invoke;即可使用调用命令的能力。 with_store方法:会自动获取指定路径的Store实例,若不存在则创建,通过闭包提供操作Store的入口。- 必须手动调用
store.save():Store仅在内存中维护数据,修改后需主动调用该方法写入文件完成持久化。
内容的提问来源于stack exchange,提问作者user14603676
相关产品推荐
相关产品推荐

