您现在的位置是:首页 >学无止境 >Vue3 使用 Ts 泛型 封装本地存储网站首页学无止境
Vue3 使用 Ts 泛型 封装本地存储
前期回顾
目录
? 本文专栏:开发技巧
新建 srcutilsstorage-utils.ts
interface StorageUtilsInterface<T> {
set(key: string, value: T): void;
get(key: string): T | null;
remove(key: string): void;
}
class LocalStorageUtils<T> implements StorageUtilsInterface<T> {
set(key: string, value: T): void {
localStorage.setItem(key, JSON.stringify(value));
}
get(key: string): T | null {
const item = localStorage.getItem(key);
if (item) {
try {
return JSON.parse(item);
} catch (error) {
console.error("Error parsing stored value:", error);
}
}
return null;
}
remove(key: string): void {
localStorage.removeItem(key);
}
}
class SessionStorageUtils<T> implements StorageUtilsInterface<T> {
set(key: string, value: T): void {
sessionStorage.setItem(key, JSON.stringify(value));
}
get(key: string): T | null {
const item = sessionStorage.getItem(key);
if (item) {
try {
return JSON.parse(item);
} catch (error) {
console.error("Error parsing stored value:", error);
}
}
return null;
}
remove(key: string): void {
sessionStorage.removeItem(key);
}
}
export { LocalStorageUtils, SessionStorageUtils };
使用
onMounted(() => {
const localStorageUtils = new LocalStorageUtils<string>();
// 设置localStorage
localStorageUtils.set("username", "张坤");
// 获取localStorage
const username = localStorageUtils.get("username");
console.log("username=====>", username); // "张坤"
// 删除localStorage
// setTimeout(() => {
// localStorageUtils.remove("username");
// }, 2000);
const sessionStorageUtils = new SessionStorageUtils<number>();
// 设置sessionStorage
sessionStorageUtils.set("age", 18);
// 获取sessionStorage
const age = sessionStorageUtils.get("age");
console.log("age=====>", age); // 18
// 删除sessionStorage
// setTimeout(() => {
// sessionStorageUtils.remove("age");
// }, 4000);
});
泛型示例
首先,什么是泛型?
泛型是一种模板机制,它允许在定义函数、类、接口等时使用类型参数(也称为类型变量),从而实现代码的复用。这里的类型参数可以是任何类型,在使用时可以传入具体的类型。
举个例子,假设我们要写一个函数来交换两个变量的值:
泛型交换变量
function swap(a: { value: any }, b: { value: any }) {
const temp = a.value;
a.value = b.value;
b.value = temp;
}
let x = { value: 1 };
let y = { value: 2 };
swap(x, y);
console.log(x.value, y.value); // 输出 2, 1
上面的代码看起来没什么问题,但是有一个问题是:函数参数的类型都是any
,也就是说这个函数可以交换任意类型的值,包括字符串、对象等等,这并不是我们想要的。
这时候,我们可以使用泛型来改进这个函数:
function swap<T>(tuple: [T, T]): [T, T] {
return [tuple[1], tuple[0]];
}
let tuple: [string, string] = ["张坤", "18"];
console.log("交换前:", tuple);
tuple = swap(tuple);
console.log("交换后:", tuple);
输出:
交换前:Array [ "张坤", "18" ]
交换后:Array [ "18", "张坤" ]
在这个例子中,我们使用了类型参数<T>
,并将其应用到函数参数上。这样,我们就可以指定要交换的值的类型。
泛型 string
接下来,再看看泛型接口StorageUtilsInterface<T>
。
这个接口定义了三个方法——set()
、get()
和remove(),它们都使用了类型参数
<T>`,表示这些方法可以处理任意类型的值。比如,如果我们用这个接口存储一个字符串类型的值:
const storage: StorageUtilsInterface<string> = new LocalStorageUtils();
storage.set('name', 'Tom');
const name = storage.get('name'); // name 的类型为 string | null
这里我们将<T>
替换成了string
,这样这个接口中的方法就会操作字符串类型的值了。
泛型 对象
如果要存储对象类型的值,可以将StorageUtilsInterface<T>
中的类型参数<T>
替换为对象类型。比如,假设我们有一个用户对象:
interface User {
name: string;
age: number;
}
const user: User = { name: 'Tom', age: 18 };
我们可以使用泛型接口StorageUtilsInterface<T>
来存储这个对象:
const storage: StorageUtilsInterface<User> = new LocalStorageUtils();
storage.set('user', user);
const savedUser = storage.get('user'); // savedUser 的类型为 User | null
这里我们将<T>
替换成了User
,这样这个接口中的方法就会操作User
类型的值了。在调用set()
方法时,我们需要将user
对象传给它,并且在调用get()
方法后,返回的值的类型也会变成User | null
,表示可能返回一个User
类型的值或者null
。
需要注意的是,在这个例子中,User
类型必须是一个可序列化的对象,即该对象可以转换为字符串并通过JSON.parse()
方法解析回来。否则,在调用set()
方法时会抛出异常。为了确保对象可序列化,我们可以为User
类型添加一个[Serializable]
标记,或者手动实现toJSON()
和fromJSON()
方法。