npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tangjie/page-localstorage

v1.1.0

Published

用于不适用keep-alive进行缓存时的一种解决方案。这是一个用于页面间通信的库,特别是在需要为这个页面存储很多项数据的时候,可以根据页面名称来操作存储在localStorage里面的数据

Downloads

18

Readme

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",()=>{
            //在这里删除所有的页面相关的客户端缓存
        })
    }
})