Browser-Storage-and-Navigation[20260807190236]

0 阅读1分钟

euv 中的浏览器存储与导航

项目代码:github.com/euv-dev/euv

在构建 Web 应用程序时,两个常见的需求是持久化数据存储和基于 URL 的导航。euv 通过其 window() 函数提供了对浏览器 API 的直接访问,让你能够与 localStoragesessionStorage 以及浏览器的 Location 对象进行交互。本文将介绍如何在 euv 框架中有效使用这些 API,包括读写存储、操作 URL 哈希值以及构建导航模式。

访问浏览器窗口

euv 中所有浏览器 API 的访问都从 window() 函数开始,它返回一个 Window 句柄。通过这个句柄,你可以访问文档、位置和各种存储机制:

let win: Window = window().expect("no global window exists");
let doc: Document = win.document().expect("should have a document");

window() 函数返回 Option<Window>,因此你应该始终处理它可能为 None 的情况(例如,在服务端渲染等非浏览器环境中运行)。实际上,对于在浏览器中运行的 WASM 应用,这总是会成功。

一旦你获得了 Window 句柄,就可以访问 Document 进行 DOM 操作,访问 Location 进行导航。

使用 localStorage

localStorage 提供了持久化的键值存储,数据在浏览器重启后仍然存在。euv 通过 Window 上的 local_storage() 方法暴露了它:

let storage: Option<Storage> = win.local_storage().unwrap_or_default();
if let Some(storage) = storage {
    let _ = storage.set_item("key", "value");
    let value: Option<String> = storage.get_item("key").unwrap_or_default();
}

让我们分解一下发生了什么:

  1. win.local_storage() 返回 Option<Storage>。如果浏览器支持 localStorage(所有现代浏览器都支持),这将返回 Some(storage)
  2. set_item("key", "value") 将值写入存储。它返回一个 Result,你可以使用 let _ = 来忽略错误。
  3. get_item("key") 从存储中读取值,返回 Option<String>.unwrap_or_default()None(键未找到)转换为空字符串。

存储复杂数据

由于 localStorage 只存储字符串,你需要对复杂数据进行序列化和反序列化。euv 的 JavaScript 互操作能力使得使用 JSON 成为可能:

let storage: Option<Storage> = win.local_storage().unwrap_or_default();
if let Some(storage) = storage {
    let _ = storage.set_item("user_name", "Alice");
    let name: Option<String> = storage.get_item("user_name").unwrap_or_default();
}

对于更复杂的场景,你可以将 spawn_localJsFuture 结合使用,通过 JavaScript 的 JSON.stringifyJSON.parse 进行序列化。

实际示例:持久化用户偏好

一个常见的用例是在不同会话之间持久化用户偏好设置:

let win: Window = window().expect("no global window exists");
let storage: Option<Storage> = win.local_storage().unwrap_or_default();
if let Some(storage) = storage {
    let _ = storage.set_item("theme", "dark");
    let theme: String = storage.get_item("theme").unwrap_or_default();
}

你可以将这与 watch! 结合使用,在响应式信号变化时自动保存偏好设置,确保存储的状态始终是最新的。

使用 Location 对象

Location 对象提供了对当前 URL 的访问以及导航方法:

let location: Location = win.location();
let hash: String = location.hash().unwrap_or_default();
let _ = location.set_hash("#/about");

读取当前哈希值

location.hash() 返回当前 URL 的哈希值(# 后面的部分),这通常用于单页应用中的客户端路由:

let location: Location = win.location();
let hash: String = location.hash().unwrap_or_default();

你可以使用这个哈希值来确定应该显示哪个视图或组件,在不重新加载页面的情况下实现客户端路由。

设置哈希值进行导航

location.set_hash() 更改 URL 哈希值,这会触发浏览器的哈希变更事件:

let _ = location.set_hash("#/about");

这会更新 URL 使其包含 #/about,而不会重新加载页面。结合条件渲染模式,你可以构建一个完整的客户端路由器:

let location: Location = win.location();
let hash: String = location.hash().unwrap_or_default();
// 使用哈希值来确定要渲染哪个页面

构建基于哈希的路由

通过将 location.hash() 与响应式信号和 watch! 结合,你可以构建一个简单但有效的路由系统:

let location: Location = win.location();
let hash: String = location.hash().unwrap_or_default();
watch!(hash, |h| {
    // 响应哈希变更并更新显示的页面
});

结合存储与导航

存储和导航通常协同工作。例如,你可能想将当前页面状态保存到存储中,这样当用户返回应用时,他们会被带到同一个页面:

let win: Window = window().expect("no global window exists");
let location: Location = win.location();
let hash: String = location.hash().unwrap_or_default();

let storage: Option<Storage> = win.local_storage().unwrap_or_default();
if let Some(storage) = storage {
    let _ = storage.set_item("last_page", &hash);
    let last_page: String = storage.get_item("last_page").unwrap_or_default();
}

这种模式通过恢复用户之前的状态来提供更好的用户体验。

使用 Document 对象

除了存储和位置,Document 对象还让你可以访问完整的 DOM:

let win: Window = window().expect("no global window exists");
let doc: Document = win.document().expect("should have a document");

你可以使用 Document 来创建元素、查询选择器以及执行其他 DOM 操作。

错误处理注意事项

浏览器 API 可能因各种原因失败——存储可能已满、浏览器可能限制访问,或者环境可能不支持某些功能。始终正确处理 OptionResult 类型:

let storage: Option<Storage> = win.local_storage().unwrap_or_default();
if let Some(storage) = storage {
    let _ = storage.set_item("key", "value");
    let value: Option<String> = storage.get_item("key").unwrap_or_default();
}

对存储使用 if let Some(...),对单个值使用 .unwrap_or_default(),确保你的应用在浏览器 API 不可用时能够优雅降级。

总结

euv 通过 window() 函数及其相关对象提供了对浏览器存储和导航 API 的直接访问。通过利用 localStorage 进行持久化数据存储、Location 进行基于 URL 的导航,以及 Document 进行 DOM 访问,你可以构建功能完备的 Web 应用程序,支持数据持久化和客户端路由。这些 API 与 euv 的响应式系统自然集成——你可以使用 watch! 响应哈希变更,将响应式信号值存储到 localStorage,并创建丰富的、感知状态的导航体验。


项目代码:github.com/euv-dev/euv