笔者之前在掘金社区的技术文章,介绍过自己项目组中负责开发的一款基于 Angular 的电商 SDK:
本文笔者会分享自己项目过程中,在设计这款 SDK 时使用 Web 开发领域的 LocalStorage 技术来实现的一个功能。
用户访问 Storefront 的 homepage,可以在 Language 的下拉菜单里,选择语言:
比如下图是语言切换成中文的效果:
同样还支持货币单位的切换:
客户的需求是,更改的这些设置,在关闭浏览器之后,仍然能够生效。意思是下次重新打开浏览器,Storefront homepage 仍然按照之前的设置去加载。
为此,我们团队采取的实现方式是,利用 Web 开发领域中的 LocalStorage 技术,来持久化用户指定的 Language 和货币单位的更改。
Local Storage 技术概述
Local Storage
技术是一种在Web 浏览器中用于客户端数据存储的机制。它允许 Web 应用程序在用户的本地浏览器上存储键值对
形式的数据,这样用户在关闭浏览器窗口或页面后,数据仍然可以保留。这为开发者提供了一种在客户端持久保存数据的简单方式,而不必依赖于服务器。
我们在 Chrome 开发者工具 Application
面板里,可以清晰观察到这些 Key Value 键值对:
Local Storage
是Web Storage API 的一部分,与 Session Storage
不同,Local Storage
的数据在关闭浏览器后仍然存在。它使用键值对的形式存储数据,其中键和值都是字符串。该技术基于域名,即同一域名下的所有页面共享相同的 Local Storage
。
使用方式也非常简单直观,使用其提供的 get 和 set API 即可。
在 JavaScript 中,通过 localStorage
对象来访问和操作 Local Storage
。以下是一些基本的 localStorage
操作:
存储数据:
// 存储数据
localStorage.setItem('username', 'John');
// 存储数字
localStorage.setItem('userAge', 25);
读取数据:
// 读取数据
const username = localStorage.getItem('username');
const userAge = localStorage.getItem('userAge');
删除数据:
// 删除数据
localStorage.removeItem('username');
清空所有数据:
// 清空所有数据
localStorage.clear();
我们项目组当时选择用 LocalStorage 技术来实现用户需求,也是基于了如下考虑:
-
持久性: 数据在浏览器关闭后仍然存在,适用于长期保存用户偏好设置等信息,比如我们项目中客户对于 Language 和货币单位的持久化需求。
-
容量:
Local Storage
允许存储较大数量的数据(通常至少5MB),相对于Cookie
的4KB而言,具备更大的容量,我们用来存储两个字符串值,可以说是绰绰有余。 -
简易性: 使用简单的键值对操作,易于理解和实现。
尽管 LocalStorage 数据存储在客户端,但是我们存储的仅仅是 Language 和货币单位,所以不存在敏感信息。
Local Storage 技术的项目实战
首先我们在 state-config.ts
文件里定义了 StorageSyncType
的枚举值:
可以看到目前我们打算支持 LocalStorage 和 SessionStorage 两种方式,方便 SDK 的 consumer 自己切换。
而 getStorage 函数用来封装获取 LocalStorage API 的行为:
export function getStorage(
storageType: StorageSyncType,
winRef: WindowRef
): Storage | undefined {
let storage: Storage | undefined;
switch (storageType) {
case StorageSyncType.LOCAL_STORAGE: {
storage = winRef.localStorage;
break;
}
case StorageSyncType.SESSION_STORAGE: {
storage = winRef.sessionStorage;
break;
}
case StorageSyncType.NO_STORAGE: {
storage = undefined;
break;
}
default: {
storage = winRef.sessionStorage;
}
}
这里 storage API 从依赖注入参数的 winRef
的 localStorage
或者 sessionStorage
字段里读取。
这两个字段都是全局对象 window
里的标准属性之一。
本文之前介绍的 LocalStorage API 就位于 localStorage 字段的原型链上,如下图高亮区域所示:
language 字段的 LocalStorage 读取
用户重新打开浏览器时,需要从 LocalStorage 里将存储的 language 字段值读取出来。
这个场景通过下图的 readFromStorage
函数实现:
export function readFromStorage(storage: Storage, key: string): unknown {
if (isSsr(storage)) {
return;
}
const storageValue = storage.getItem(key);
if (!storageValue) {
return;
}
return JSON.parse(storageValue);
}
逻辑很直接,首先判断是否是在 SSR 环境下,如果是就直接返回。因为按照笔者这篇文章的介绍,用户的个性化设置和私有数据页面,比如购物车,WishList 等,不应该被 Angular 服务器端渲染考虑,所以我们代码里如果 isSsr
检测函数返回 true,直接返回;否则调用 storage
的 API 即 getItem
返回浏览器 LocalStorage 里的存储值。
下面是调试器里的截图:
language 字段的 LocalStorage 的写入
当用户在 Storefront 界面上用下拉菜单更换 Language 字段值时,会调用 browser-storage.ts
里的 persistToStorage
方法:
我们可以看到这个方法里调用代码第 44 行的 setItem
,将 Angular UI 上用户选定的值写入到 LocalStorage 里。
下拉菜单的实现位于 site-context-selector.component.html
文件内部。当用户切换下拉菜单值的时候,触发第 3 行 select
元素的 change 事件。
事件的处理函数主体就只有一个 active = $any($event).target.value
的赋值操作,这会触发定义在 active
属性上的 set 方法:
set 方法里调用 this.componentService.setActive(value, this.context)
,这个函数调用最终把执行投递到 storage.setItem(configKey, JSON.stringify(value))
上去:
总结
在 Local Storage 出现之前,客户端数据存储主要依赖于 cookies。但是,cookies 存在许多不足,比如存储空间有限(通常只有 4KB),数据在每次 HTTP 请求时都会被发送到服务器,这会消耗更多的带宽。相比之下,Local Storage 提供了更大的存储空间(通常是 5MB),并且数据只存储在客户端,不会被发送到服务器。这使得 Local Storage 成为一种更有效的客户端数据存储方式。
本文介绍了笔者在实际 Angular 开发项目中使用 Local Storage 来持久化用户个性化选择的一个案例,希望能帮助到需要实现类似功能的开发者们。
标签:存储,场景,Storage,storage,LocalStorage,localStorage,Local,Angular From: https://www.cnblogs.com/sap-jerry/p/17860837.html