欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Vue中localstorage和sessionstorage的使用

程序员文章站 2022-10-30 15:41:52
1. 项目使用中暴露出来的几个问题 大家到处直接使用localstorage['aaa']='这是一段示例字符串'这些原生语法实现,这样耦合度太高了,假如有一天我们需要换...

1. 项目使用中暴露出来的几个问题

大家到处直接使用localstorage['aaa']='这是一段示例字符串'这些原生语法实现,这样耦合度太高了,假如有一天我们需要换实现方式,或者对存储大小做一些控制,那么需要修改的代码就会很多

项目很大,那么大家起的key的名字难免会重复,而且这样也会造成全局污染

因为localstorage的使用不规范,所以造成了存储空间的浪费和不够用

2. 解决办法

封装storage的使用方法,统一处理

规范storage的key值的命名规则
规范storage的使用规范

2.1. 封装统一的方法

封装成方法可以降低耦合度,可以方便切换实现方式,可以控制存储量大小

改变实现可以通过配置不同的参数来实现

编辑如图所示的项目结构

代码实现

/*
 * storage.js
 */
/*
 * @author: 石国庆
 * @desc: 本地数据存储方法封装
 * @date: 2017.11.14
 * @ref:
 *  https://github.com/wqteam/web-storage-cache
 *  https://developer.mozilla.org/en-us/docs/web/api/storage/localstorage
 * @explain:为了不new对象,只能多写几遍
 * @example:
 *
 * 1、localstorage的使用
 * import storage from '@/utils/storage.js'
 * storage.setitem('shiguoqing0',[1,2,3,4,5,6])
 * storage.setitem('shiguoqing1',{userid:'dfdf',token:11232323})
 * storage.setitem('shiguoqing2','dfdfdf')
 * console.log(storage.getitem('shiguoqing0'))
 * console.log(storage.getitem('shiguoqing1'))
 * console.log(storage.getitem('shiguoqing2'))
 * storage.removeitem('shiguoqing2')
 *
 *
 * 2、sessionstorage的使用
 * storage.setitem('shiguoqing0',[1,2,3,4,5,6],{type:'session'})
 *
 * */
// todo:其他方法的实现
// todo:超时时间的设置
/*
 * 方法实现
 * */
import local from './storage/localstorage.js'
import session from './storage/session.js'
import cookies from './storage/cookies.js'
import json from './storage/json.js'
/*
* 函数体
* */
let storage= {
 config:{
  type:'local',// local,session,cookies,json
  expires:new date().gettime() + 100 * 24 * 60 * 60 * 1000
 },
 getstorage(options){
  let config={}
  if(options){
   config=object.assign({},this.config,options)
  }else{
   config=this.config
  }
  return this.createstorage(config.type)
 },
 createstorage(name){
  switch(name){
   case 'local':return local;break
   case 'session':return session;break
   case 'cookies':return cookies;break
   case 'json':return json;break
  }
 },
 getitem(key,options){
  let store=this.getstorage(options)
  return store.getitem(key)
 },
 setitem(key, value,options){
  let store=this.getstorage(options)
  store.setitem(key,value)
 },
 removeitem(key,options){
  let store=this.getstorage(options)
  store.removeitem(key)
 },
 getall(){},
 clear(options){
  let store=this.getstorage(options)
  store.clear()
 },
 key(n){},
 lenght(){},
 has(key){},
 foreach(cb){},
 deleteallexpires(){},
 // 获取最大存储空间:只有localstorage和sessionstorage可以使用这个方法
 getmaxspace(options){
  let store=this.getstorage(options)
  store.getmaxspace()
 },
 // 获取使用了的空间:只有localstorage和sessionstorage可以使用这个方法
 getusedspace(options){
  let store=this.getstorage(options)
  store.getusedspace()
 }
}
export default storage
// https://segmentfault.com/a/1190000002458488
// 5、遍历localstorage存储的key
//  .length 数据总量,例:localstorage.length
//  .key(index) 获取key,例:var key=localstorage.key(index);
// 备注:localstorage存数的数据是不能跨浏览器共用的,一个浏览器只能读取各自浏览器的数据,储存空间5m。
// 超时设置
// function(st, key, value, expires) {
//  if (st == 'l') {
//   st = window.localstorage;
//   expires = expires || 60;
//  } else {
//   st = window.sessionstorage;
//   expires = expires || 5;
//  }
//  if (typeof value != 'undefined') {
//   try {
//    return st.setitem(key, json.stringify({
//     data: value,
//     expires: new date().gettime() + expires * 1000 * 60
//    }));
//   } catch (e) {}
//  } else {
//   var result = json.parse(st.getitem(key) || '{}');
//   if (result && new date().gettime() < result.expires) {
//    return result.data;
//   } else {
//    st.removeitem(key);
//    return null;
//   }
//  }
// }
/*
 * localstorage.js
 * localstorage的实现
 */
// 这个有点奇怪,文件名称叫local.js不能按照js文件解析
export default {
 getitem(key){
  let item = localstorage.getitem(key)
  // 这点要判断是字符串还是对象
  let result = /^[{\[].*[}\]]$/g.test(item)
  if (result) {
   return json.parse(item)
  } else {
   return item
  }
 },
 setitem(key, value){
  // 这点要判断是字符串还是对象
  if (typeof value == "string") {
   localstorage.setitem(key, value)
  } else {
   let item = json.stringify(value)
   localstorage.setitem(key, item)
  }
 },
 removeitem(key){
  localstorage.removeitem(key)
 },
 getall(){},
 clear(){
  localstorage.clear()
 },
 key(n){},
 foreach(cb){},
 has(key){},
 deleteallexpires(){},
 // 获取localstorage最大存储容量
 getmaxspace(){
  if (!window.localstorage) {
   console.log('当前浏览器不支持localstorage!')
  }
  var test = '0123456789'
  var add = function (num) {
   num += num
   if (num.length == 10240) {
    test = num
    return
   }
   add(num)
  }
  add(test)
  var sum = test
  var show = setinterval(function () {
   sum += test
   try {
    window.localstorage.removeitem('test')
    window.localstorage.setitem('test', sum)
    console.log(sum.length / 1024 + 'kb')
   } catch (e) {
    console.log(sum.length / 1024 + 'kb超出最大限制')
    clearinterval(show)
   }
  }, 0.1)
 },
 // 获取使用了的localstorage的空间
 getusedspace(){
  if (!window.localstorage) {
   console.log('浏览器不支持localstorage')
  }
  var size = 0
  for (item in window.localstorage) {
   if (window.localstorage.hasownproperty(item)) {
    size += window.localstorage.getitem(item).length
   }
  }
  console.log('当前localstorage使用容量为' + (size / 1024).tofixed(2) + 'kb')
 }
}
/*
 * session.js
 * sessionstorage的实现
 */
export default {
 getitem(key){
  let item = sessionstorage.getitem(key)
  // 这点要判断是字符串还是对象
  let result = /^[{\[].*[}\]]$/g.test(item)
  if (result) {
   return json.parse(item)
  } else {
   return item
  }
 },
 setitem(key, value){
  // 这点要判断是字符串还是对象
  if (typeof value == "string") {
   sessionstorage.setitem(key, value)
  } else {
   let item = json.stringify(value)
   sessionstorage.setitem(key, item)
  }
 },
 removeitem(key){
  sessionstorage.removeitem(key)
 },
 getall(){},
 clear(){
  sessionstorage.clear()
 },
 key(n){},
 foreach(cb){},
 has(key){},
 deleteallexpires(){},
 // 获取localstorage最大存储容量
 getmaxspace(){
  if (!window.sessionstorage) {
   console.log('当前浏览器不支持sessionstorage!')
  }
  var test = '0123456789'
  var add = function (num) {
   num += num
   if (num.length == 10240) {
    test = num
    return
   }
   add(num)
  }
  add(test)
  var sum = test
  var show = setinterval(function () {
   sum += test
   try {
    window.sessionstorage.removeitem('test')
    window.sessionstorage.setitem('test', sum)
    console.log(sum.length / 1024 + 'kb')
   } catch (e) {
    console.log(sum.length / 1024 + 'kb超出最大限制')
    clearinterval(show)
   }
  }, 0.1)
 },
 // 获取使用了的localstorage的空间
 getusedspace(){
  if (!window.sessionstorage) {
   console.log('浏览器不支持sessionstorage')
  }
  var size = 0
  for (item in window.sessionstorage) {
   if (window.sessionstorage.hasownproperty(item)) {
    size += window.sessionstorage.getitem(item).length
   }
  }
  console.log('当前sessionstorage使用容量为' + (size / 1024).tofixed(2) + 'kb')
 }
}
/*
 * cookies.js
 * cooikes的实现,这辈子估计没有时间实现了
 */
export default {
 getitem(key){},
 setitem(key, value){},
 removeitem(key){},
 getall(){},
 clear(){},
 key(n){},
 foreach(cb){},
 has(key){},
 deleteallexpires(){}
}
/*
 * json.js
 * json的实现,这辈子估计也没有时间实现了
 */
export default {
 getitem(key){},
 setitem(key, value){},
 removeitem(key){},
 getall(){},
 clear(){},
 key(n){},
 foreach(cb){},
 has(key){},
 deleteallexpires(){}
}

2.2. 规范命名空间的使用

为了防止key值污染,我们可以合理使用命名空间

我们可以定义命名空间,但是不能把很多数据存储在同一对象里面,这样后面的操作量会太大

比如全局的在global下面

比如各功能系统的加上系统词缀

一个系统的命名空间规范应该提前设计好,否则真正开发起来会有很多人不按照规则使用

全局使用的东西要在readme.md文档中体现出来

示例

* localstorage['sgq.global.userauthor']:登录的用户信息都在这里,菜单,组织,集团
* localstorage['sgq.global.systemname']:登录的系统名称
* localstorage['sgq.vuex.state']:vuex中的state的存储地址,这里面有所有的的东西
* localstorage['sgq.wms.warehouse']:wms需要的仓库信息
+ localstorage['sgq.wms.warehouse'].permissionid
+ localstorage['sgq.wms.warehouse'].dataresource
* localstorage['sgq.tms.org']:tms需要的网点的信息
+ localstorage['sgq.tms.org'].permissionid
+ localstorage['sgq.tms.org'].orgname

2.3. storage使用规范

2.3.1. 问题产生的原因

这个问题的产生是因为我们要做权限登录,然后登录的时候一直报存储空间不够的问题,查了原因发现是后端把所有的超管的几千条数据都返回来了,以至于不够用,后来修改了后端接口返回的数据内容解决了这个问题。

但是这次的事给我们带来了几点思考?

localstorage和sessionstorage的存储量在不同的浏览器中基本是5m

localstorage和sessionstorage的存储是跟着域名来的

boss.hivescm.com下localstorage存储是5m

b2b.hivescm.com下localstorage存储也是5m

即使这次问题解决了,但是我们应该定一套方案,充分利用一个域名下,localstorage和sessionstorage的共10m空间

2.3.2. storage使用方案

全局使用的东西,共享的东西,永久存储的东西储存在localstorage中

不需要永久存储的东西在使用完毕之后要记得及时清除

如果数据量过大就不要存储在本地了,变为动态获取

可以使用存储量更大的indexeddb,不过有兼容性问题

可以在实现方案中对要存储到storage中的东西做字数限制

充分合理利用sessionstorage和localstorage的h5特性

例如:列表数据存储在vuex中其实也会存到localstorage

例如:表单校验的一些数据都用sessionstorage

3. 其他

3.1. 延伸扩展

由此可以类推到事件的处理,没用的事件要及时在退出vue组件的时候清理掉

例如:this.bus.$on('aa')要用this.bus.$off('aa')卸载事件

3.2. 字符长短获取

var len = 0
for (var i = 0; i < val.length; i++) {
 if (val[i].match(/[^\x00-\xff]/ig) != null) //全角
  len += 2 //如果是全角,占用两个字节 如果mysql中某字段是text, 如果设置编码为utf-8,那么一个中文是占3个字节, gbk是两个字节
 else
  len += 1 //半角占用一个字节
}
return len

以上就是小编整理的关于vue中localstorage和sessionstorage的用法的全部内容,感谢你对的支持。