为什么会有上面的这个想法呢?
1、我在公司的wx小程序项目中开到之前的前端小姐姐自己封装的storage,下图
前几次用的时候,我还是蛮顺手的,用了特别多次数之后,我就在想为什么我每次都需要xxx.get(),就不能直接xxx进行获取数据吗?正好这几天我在开发自己的工具插件,于是就想着也实现一下这种功能。
2、我个人主要从事web端开发,编写的插件也是web端的,在web端wx.getStorageSync的平替为window.localStorage,上述的两种原因演变出来了本文的标题。
最初的版本
{
const storage_get = (name) => JSON.parse(window.localStorage.getItem(name))
const storage_set = (name, val) => window.localStorage.getItem(name, JSON.stringify(val))
}
这个真没开玩笑,我最初的版本真是这样的,每次用的时候只需要storage_get(xxx)、storage_set(xxx)就行了,我当初还特意加了JSON.stringify、parse来减少使用时的步骤。直到某天半夜,我爬了起来,给了自己两巴掌,**,这样用和xxx.get()有什么区别?这不就是换了个壳子? 于是我趁着周末写了第二个版本。
2.0
在写第二个版本的时候我就在想如果能window.localStorage.xxx直接获取xxx数据,或者window.localStorage.xxx="a"能够直接设置数据不就是方便很多了?出于这种思想下,我编写了2.0
const init = (arr = []) => {
const _get = (val) => JSON.parse(window.localStorage.getItem(val))
const _set = (key, val) => window.localStorage.setItem(key, JSON.stringify(val))
// 代理的内容
let STORAGE = {}
//name的合集
let key_list = []
arr.forEach(item => {
if (typeof (item) == 'string') {
key_list.push(item)
STORAGE[item] = item
}
})
const storage = new Proxy(STORAGE, {
get(target, key) {
if (key === '$') {
return _set
} else {
return _get(key)
}
},
set(target, key, val) {
if (key_list.includes(key)) {
_set(key, val)
return true
} else {
return false
}
}
})
//请各位忽略掉我代码中的'',正常情况我都是用""包裹字符串的
return storage
}
2.0版本的使用方法
//....
//👆引入js文件
const arr = ['token', 'userinfo']
const storage = init(arr)
storage.userinfo = { id: 173, name: 'tjq', time: '1234' } //更新window.localStorage的数据
//或者 storage.$('userinfo',{name:'tjq'})
console.log(storage.userinfo); //{ id: 173, name: 'tjq', time: '1234777' }
说真的,到这里我真的以为结束了,我已经认为我就是万中无一的前端天才了,我怀着强烈的自豪感去在我的个人项目中使用时,结果天塌了。
2.1版本
为什么说2.0版本是天塌了?因为我压根没有考虑场景,而是一味的散发我的个人魅力(代码的魅力,另外本人183)
1、我没有考虑到默认值问题(我在使用token时有个习惯,如果是测试环境,token写死,用默认值,生产环境才会调取后端接口)
2、时效性(我个人项目的用户token是有时效性的,前端/后端都有,用了我这个2.0版本,我之前写的失效功能就没用了)
....
看到上述的两个问题,我不由头大,因为其它类似的问题肯定还有很多很多,只是我暂时没有遇到,怀揣着悲伤的情绪我编写了2.1版本(增加了默认值功能,时效性我还在想)
const useStorage = (data) => {
const arr = data
/**
const arr = [
{
// 本地存储的名称
name: "userinfo",
//描述信息,最好要有
desc: "存储用户信息",
// 日后可扩展功能:时效性
time: 7 * 1000,
//初始值
value: "初始值",
}
]
// 或者 ↓
const arr = ['userinfo']
*/
const _get = (val) => JSON.parse(window.localStorage.getItem(val))
const _set = (key, val) => window.localStorage.setItem(key, JSON.stringify(val))
// 代理的内容
let STORAGE = {}
//name的合集
let key_list = []
arr.forEach(item => {
if (item instanceof Object) {
let { name, desc = false, value ,time} = item
if (desc == false) {
console.warn("您尚未编写注释来介绍" + name + "的作用")
}
if (value) {
_set(name,value)
}
key_list.push(name)
STORAGE[name] = {
...item
}
} else if (typeof (item) == 'string') {
key_list.push(item)
STORAGE[item] = item
}
})
const storage = new Proxy(STORAGE, {
get(target, key) {
if (key === '$') {
return _set
} else {
return _get(key)
}
},
set(target, key, val) {
if (key_list.includes(key)) {
_set(key, val)
return true
} else {
return false
}
}
})
return storage
}
//...
//👆引入文件
const storage = useStorage([{
name:"token",
value:"默认的token",
desc:"存储token"
}])
export default storage