You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:35:06