Skip to content

让我们从定义持久状态到底是什么开始。持久状态基本上是指存储在用户计算机上的任何数据,当应用程序关闭时,这些数据不会丢失。这与临时状态不同,临时状态通常保存在内存中,在应用程序关闭后就消失了。

持久状态还可以存储在云中,这对于跨平台同步(比如从 Web 到 Desktop,或者从 Desktop 到 Mobile)非常有用。然而,这超出了这篇文章的范围。我们只关注本州。

将持续状态分为两类可能是有用的,因为每种治疗方法不同:

  • 通常由用户生成,或从互联网取出并存储在本地。它可能是待办事项应用程序上的项目列表,音乐播放器上的音乐列表,或 CRM 上的联系人列表
  • 是用于自定义应用程序的设置,如主题、语言、默认排序列或窗口大小。一些首选项可以由用户设置,但其他首选项可以由应用程序自动设置,比如最后一个窗口的大小

让我们来探索一些在 Tauri 应用程序中同时存储用户数据和应用程序首选项的选项。

1. Webview 本地存储

这是存储持久状态的最基本的选项。它内置在 webview 中,JavaScript 可以通过 window.localStorage 对象使用它。它是一个简单的键值存储,值以字符串的形式存储。

localStorage.setItem("app-theme", "dark");

const theme = localStorage.getItem("app-theme");

这个选项的最大好处之一就是简单性。同步还使得在各种情况下(比如 React/Vue/Svelte 状态)使用它变得非常容易。

另一方面,也有一些不利之处。最大的问题是,它只能通过 JavaScript 访问,不能从 Rust 访问。它的另一个负面影响是3 ~ 5MB 的存储限制(取决于平台)。这是一个很大的存储,但它不是无限的。如果您需要存储大量数据,那么这个工具不适合。

等等,本地存储真的是持久的吗?

是的。数据存储在用户的计算机上,当应用程序关闭时,数据不会丢失。在 Tauri 应用程序的上下文中,如果用户决定清除他们的浏览器缓存,它也不会被删除。该应用程序完全控制什么存储在本地存储和何时删除它。用户可以进去手动删除文件,但是用户必须知道他们在做什么以及这样做的后果。

本地存储将是我存储应用程序首选项的第一选择,但是考虑到存储限制,绝对不是用户数据的一个选项。

2. IndexedDB

这有点类似于本地存储,但它是异步的,可以存储更多的数据。JavaScript 也可以通过 window.indexedDB 对象使用它。

与本地存储相比,它的使用有点麻烦,主要是因为它是异步的,但也因为它更接近于实际的数据库,支持索引、表、事务等。可用的文档也较少,它不像本地存储那样广为人知和使用。

一般来说,我不推荐 IndexedDB 用于存储 App Preferences,但对于用户数据来说,它可能是一个不错的选择。尽管我个人更喜欢使用实际的用户数据库,比如 SQLite,我们将很快讨论它。

3. tauri-plugin-store

接下来是 Tauri-plugin-store,它是用于在 Tauri 应用程序中存储持久状态的官方插件。它是文件系统的包装器,有一个 JavaScript 可用的 API。

通过这个插件,我们可以更好地控制数据的存储位置,并且可以从 Rust 访问它。由于 JavaScript-Rust IPC 的原因,API 必须是异步的,但是使用起来仍然非常简单。

import { Store } from "tauri-plugin-store-api";

const store = new Store(".settings.json");

await store.set("app-theme", "dark");
await store.save();

const theme = await store.get("app-theme");

这个插件基本上会创建一个。Json 文件位于应用程序的数据目录中,这对于每个平台都是不同的。但是因为它只是一个普通的文件系统文档,所以它的存储空间不限于3 ~ 5MB。

等等!没有限制并不意味着你应该把所有东西都存在那里。此插件用于存储应用程序首选项,而不是用户数据。如果需要存储大量数据,应该使用实际的数据库,我们将在下面讨论这个问题。

4. tauri-plugin-sql

如果您在与 SQL 数据库进行某种程度的交互之前已经使用过后端系统。Tauri-plugin-SQL 是 Tauri 应用程序中用于连接任何 SQL 数据库的官方插件。

除非您正在构建 SQL 客户端,否则可能需要使用 SQLite。它是一个简单的、基于文件的数据库,易于使用,不需要服务器。它非常适合存储桌面和移动应用程序的数据。虽然 tauri-plugin-sql 支持 SQLite,但是您也可以使用其他 Rust 板条箱来滚动自己的实现,就像本文在 MoonGuard How to use local SQLite database with tauri 中介绍的那样,它还有一个额外的好处,那就是可以完全控制实现。

通过使用 SQLite,您可以在应用程序中获得实际 OLTP 数据库的所有好处,例如索引、事务等等。使用 tauri-plugin-sql,您还可以同时执行 Rust 和 JavaScript 的查询,这是一个巨大的好处。

在我看来,这是非常适合存储用户数据和应用程序首选项,虽然我可能会建议更多的用户数据。

比较

特写本地仓库IndexedDB
简单
从 Rust 读/写没有没有
从 JavaScript 读/写是的是的
异步还是同步同步异步
最好的应用程序偏好用户资料

想听听我的建议吗?

  • 我 用户不介意丢失的东西;
  • 我 对于后端首选项是有点关键,如 API 键,许可证键和其他更敏感的数据,因为我有更多的控制如何和在哪里存储的数据;
  • 我 因为像 Sqlite 这样的真实数据库的灵活性和强大功能,所有的长期和更大的数据集;