1.1.0 • Published 3 years ago

@tangjie/page-localstorage v1.1.0

Weekly downloads
11
License
MIT
Repository
-
Last release
3 years ago

page-localstorage

主要用于存储主页面的数据给详情页面使用,并在详情页面返回主页面时进行数据回显。

主要有以下特点

  • 可以存储value为对象的情况,并且用户value的序列化和反序列化是无感知的。
  • 可以直接以({key1:value1,key2:value2,...})的形式一次性存储大量的数据,免去了写大量setItem()的麻烦,同时代码也不优雅。
  • 在实例化后,可以直接根据传递的pageName页面名称来获取存储在本地的缓存数据,免去了写很多getItem()的麻烦。
  • 删除数据也不用写很多的removeItem()了,直接实例化时,调用删除缓存的方法就行了。会根据实例的pageName或者传递的页面。
  • 在页面刷新前后,对缓存在本地的数据的操作方法不变。

这个工具包里主要有以下方法:

1、构造函数

这里的构造函数准确来说是一个工厂函数。以该函数原型对象上的init函数来作为构造函数,并将init函数的原型指向构造函数的原型。这样我们实例化init函数时,获取到的实例也能获取到该构造函数上的原型属性。 在在init函数中初始化实例,使用bind函数将this传递到需要使用实例的函数中。表面this隐式丢失。

function LocalStorageClass (pageName) {
    return  new LocalStorageClass.prototype.init(pageName);
}
init(pageName){
    // 用于保存页面名称
    this.pageName = pageName;
    // 保存页面设置缓存的key
    this.storageKeys = [];
    //利用bind来使在调用一些实例方法时,使this指向实例
    this.setStorage = this.setStorage.bind(this);
    this.removeStorage = this.removeStorage.bind(this);
    this.getStorage = this.getStorage.bind(this);
    this.removeStorageByPageName=this.removeStorageByPageName.bind(this);
    this.removeAllPageStorage=this.removeAllPageStorage.bind(this);
}

2、静态属性

构造函数对象上有3个静态属性:分别是instanceObjpageNamescreateInstance

// 用于存储单例对象
LocalStorageClass.instanceObj = Object.create(null);
//主要用于在刷新页面后数据(pageName)丢失的问题
LocalStorageClass.pageNames=[];
// 单例
LocalStorageClass.createInstance

3、获取实例

这里使用了单例模式,来减少性能开销。并且使用一个静态对象来存储实例对象。键为页面名称,值为实例对象。

function createInstance(pageName) {
    if(typeof window!=='object'){
        throw new Error("当前库只适用于浏览器环境");
    }
    if (!window.localStorage) {
        throw new Error("当前浏览器不支持localStorage");
    }
    // this.instanceObj[pageName] 用于保存实例对象
    if (this.instanceObj[pageName]) {
        return this.instanceObj[pageName];
    }
    return this.instanceObj[pageName] = new LocalStorageClass(pageName);

4、设置缓存

在这里会考虑是以 setStorage({key:value}) 形式传递过来,还是以 setStorage(key:value) 的形式传递过来。 同时还对整个页面的key的数组进行一个缓存。key为传递进来的pageName:page,值value为该页面需要缓存的数据的key组成的数组(这里的key后天添加一个:page是为了避免key值重复)。这样设置的原因是避免页面刷新获取不到页面keys的问题这里在处理value为对象的情况时,会将value转换为字符串,并在字符串最后添加:object以示区分

setStorage function(...args){
    ...
     //为页面设置keys数组 
    this.pageName && localStorage.setItem(`${this.pageName}:${PAGE}`, this.storageKeys);
}

5、获取缓存

获取缓存时,会区分传递一个key和多个key的情况。一个key时,直接返回key对应的值;传递多个key时,返回一个对象。 在获取的值的字符串后面以:object结尾时,会默认将值转换为对象,很好的避免了后面拿到值再去判断是否是对象的不足。

getStorage function(...args){
    ...
    this._resolveObjectValue();
}
function _resolveObjectValue (key) {
        this._resolveKey(key);
        let value = localStorage.getItem(key);
        const len = OBJECT.length + 1;
        if (typeof value === "string" && value.slice(-len) === `:${OBJECT}`) {
            value = JSON.parse(value.slice(0, -len));
        }
        return value;
    },

6、删除缓存

在这里提供了三个方法来删除缓存。

方法 1 removeStorage (filterkeys = [], needRmKeys=[])

在这个方法中删除缓存时,考虑三种情况。

  • 页面名称pageName不存在的情况,不做任何处理
if (!this.pageName) {
    return;
}
  • 没有传递需要删除的keys的情况 这是删除pageName对应页面所有key对应的缓存值
if (filterkeys.length === 0 && needRmKeys.length === 0) {
    this.removeStorageByPageName();
    return;
}
  • 没有传递需要删除的keys,但是传递了不想删除的keys的情况
const pageKeys = this._getKeysByPageName();
//没有传递参数的情况 这是删除pageName对应页面所有key对应的缓存值
if (needRmKeys.length === 0) {
    //避免因为页面刷新,导致storageKeys为空,到时缓存清除不了的问题
    let storageKeys = this.storageKeys;

    if (storageKeys.length === 0 && pageKeys.length > 0) {
        storageKeys = pageKeys;
    }
    const keys = storageKeys.filter(key => !filterkeys.includes(key));
    this._removeItem(keys, pageKeys);
}
  • 删除传入参数中不包含在filterkeyskey的对应值
const pageKeys = this._getKeysByPageName();
const keys = needRmKeys.filter(key => !filterkeys.includes(key));
this._removeItem(keys,pageKeys);

方法 2 removeStorageByPageName (pageName)

根据页面名称删除当前页面对应的缓存。

 removeStorageByPageName (pageName = this.pageName) {
    let pageKeysStr = localStorage.getItem(`${pageName}:${PAGE}`);
    if (pageKeysStr) {
        const storageKeys = pageKeysStr.split(",");
        this._removeItem(storageKeys);
        //删除页面对应的所有key
        localStorage.removeItem(`${pageName}:${PAGE}`);
    }
    //从静态页面数组中删除指定页面,同时从缓存中也删除指定页面
    const pageNames = LocalStorageClass.pageNames
    const index = pageNames.indexOf(pageName);
    if (index > -1) {
        pageNames.splice(index, 1);
        localStorage.setItem(`${PAGENAMES}:${PAGENAMES}`, pageNames);
    }
}

方法 3 removeAllPageStorage()

删除所有页面保存在客户端的缓存。

 //避免页面刷新获取不到页面keys的问题
let pageNames = localStorage.getItem(`${PAGENAMES}:${PAGENAMES}`)
if (pageNames) {
    pageNames = pageNames.split(",");
    each(pageNames, (_, pageName) => {
        this.removeStorageByPageName(pageName);
    })
    localStorage.removeItem(`${PAGENAMES}:${PAGENAMES}`)
}

注意:在页面卸载时需要注意删除所有页面对应的缓存,避免占用不必要的客户端内存。

//处理方法1 全局混入
Vue.mixin({
     beforecreate(){
        window.addEventListener("unload",()=>{
            //在这里删除所有的页面相关的客户端缓存
        })
    }
})
1.1.0

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago