在我們之前的文章中 (Day 10),曾經提到了如何使用 Tauri 內建的 State
功能來管理應用程式的狀態。State
非常適合用來處理應用程式運行期間的即時狀態,但當應用程式關閉後,這些狀態就會消失。如果我們希望某些資料能夠被永久保存,例如使用者的設定、視窗大小與位置等,這時候就需要一個能夠將資料寫入檔案的解決方案。
今天,我們將介紹一個官方維護的插件 tauri-plugin-store
,它提供了一個簡單好用的 Key-Value 儲存方案,讓我們可以輕鬆地在前端與後端之間讀寫持久化的資料。
在深入 tauri-plugin-store
之前,讓我們先快速釐清一下它與之前提到的 State
的區別:
tauri::State
:
tauri-plugin-store
:
簡單來說,如果你需要一個關閉程式後就消失的暫時狀態,用 State
;如果你需要一個能永久保存的設定檔,那就用 store
插件。這兩者並不互斥,在一個複雜的應用中,通常會兩者並用。
不同作業系統會把資料儲存在不同位置,以 Windows 為例,會儲存在 AppData 的 Roaming 資料夾中。
tauri-plugin-store
Tauri 的 plugin 的安裝都很簡單,只要下這個指令就可以自動安裝了:
npm run tauri add store
安裝完之後,理論上就可以直接使用了。之後如果有需要,記得去調整 capabilities,給予合適的權限、預設是給予 store:default
權限:
{
"permissions": [
...,
+ "store:default",
]
}
讓我們來實作一個非常簡單的範例:在後端寫入一個設定值,然後在前端讀取它。
我們可以在任何一個前端元件中,透過 Store
class 來操作資料。預設情況下,它會將資料儲存在一個名為 store.json
的檔案中。讓我們來調整一下預設範例:
import { ref, onMounted } from "vue";
import { invoke } from "@tauri-apps/api/core";
import { Store } from "@tauri-apps/plugin-store";
const greetMsg = ref("");
const name = ref("");
const greetName = ref("");
let store: Store;
async function greet() {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
greetMsg.value = await invoke("greet", { name: name.value });
greetName.value = name.value;
// // 也可以直接在前端儲存姓名到 store
// if (store) {
// await store.set("name", name.value);
// await store.save();
// }
}
// 在元件掛載時載入 store 中的姓名
onMounted(async () => {
// 載入 store (也可以不給參數,預設會是 store.json)
store = await Store.load("user-data.json");
// 檢查是否有儲存的姓名
const storedName = await store.get<string>("name");
if (storedName) {
greetName.value = storedName;
}
});
並在 <template>
中找個地方呈現一下 greetName
<h2 v-if="greetName !== ''">Welcome back~ {{ greetName }}~</h2>
在後端,我們通常會在 setup
或是某個 command
中存取 store。
讓我們直接修改範例 greet
:
use tauri::AppHandle;
use tauri_plugin_store::StoreExt;
#[tauri::command]
fn greet(name: &str, app: AppHandle) -> Result<String, String> {
// 取得 store 實例
let store = app.store("user-data.json").map_err(|e| e.to_string())?;
// 儲存姓名到 store
store.set("name", serde_json::Value::String(name.to_string()));
// 儲存 store 到檔案
if let Err(e) = store.save() {
return Err(format!("Failed to save store: {}", e));
}
Ok(format!("Hello, {}! You've been greeted from Rust!", name))
}
這樣就完成了!
一開始什麼都沒有
接下來隨便輸入一個名字,按下 Greet 按鈕。可以看到上面多了一行副標題,輸入框下方也有一行小字 (原本的範例就有的)。
接下來,關閉程式後,再次打開。就會自動載入 Store,顯示名字在副標題。
使用 tauri-plugin-store
時,有幾個重要的最佳實踐需要注意。首先,記得呼叫 save()
方法來確保資料真正寫入磁碟,否則資料可能只存在於記憶體中。其次,合理地組織資料結構,避免儲存過於複雜的巢狀物件,這有助於提升讀寫效能。
此外,考慮到使用者隱私,敏感資料應該經過適當的加密處理,而不是直接以明文形式儲存。對於大量資料的儲存,建議考慮使用更專業的資料庫解決方案。
透過這個簡單的範例,我們可以看到 tauri-plugin-store
如何輕鬆地在前後端之間建立一個持久化的資料橋樑。這對於儲存使用者設定、應用程式配置等場景非常有用。
今天我們介紹了 store
插件的用途、安裝方式以及一個基礎的範例。在接下來的文章中,我們會繼續探索更多實用的 Tauri 插件!