业务层hooks封装useSessionStorage实例详解

目录
  • 封装原因:
    • 建议:
  • 工具库封装模式:
    • 工具库目录:
  • API设计:
    • 代码实践:
  • Hooks设计方式
    • useSessionStorage.js
    • 简介:
    • 注意点
  • Api
    • Params
    • Options
    • Result
  • 总结:

封装原因:

名称:useSessionStorage

功能开发过程中,需要进行数据的临时存储,正常情况下,使用localStorage或者 sessionStorage,存在于 window 对象中,使用场景不一样。

sessionStorage的生命周期是在浏览器关闭前,浏览器关闭后自动清理,页面刷新不会清理。

localStorage的生命周期是永久性的,存储的数据需要手动删除。

建议:

  • 存储业务数据,登录会话内,使用sessionStorage。
  • 需要持久化话的数据,比如token标记之类的可以使用localStorage,使用时需要谨慎对待,以及考虑清理时机。

工具库封装模式:

工具库目录:

API设计:

  • 获取本地存储 getCache
  • 写入本地存储 setCache
  • 设置用户缓存 setUserCache
  • 获取用户缓存getUserCache
  • 移除cookie removeCookies

代码实践:

import Cookie from 'js-cookie';
/**
 * 获取缓存数据
 * @param {string} key
 * @param {string} type: 缓存类型 'local'(默认) / cookie / session;
 */
function getCache(key, type = 'local') {
  let data;
  switch (type) {
    case 'cookie':
      data = Cookie.get(key);
      break;
    case 'session':
      // eslint-disable-next-line no-case-declarations
      let strS = sessionStorage.getItem(key);
      try {
        data = JSON.parse(strS);
      } catch (e) {
        data = strS;
      }
      break;
    default:
      // eslint-disable-next-line no-case-declarations
      let strL = localStorage.getItem(key);
      try {
        data = JSON.parse(strL);
      } catch (e) {
        data = strL;
      }
      break;
  }
  return data;
}
/**
 * 获取缓存数据
 * @param {string} key
 * @param {any} value
 * @param {string} type: 缓存类型 'local'(默认) / cookie / session;
 */
function setCache(key, value, type = 'local') {
  switch (type) {
    case 'cookie':
      Cookie.set(key, value, { expires: 7 });
      break;
    case 'session':
      sessionStorage.setItem(key, JSON.stringify(value));
      break;
    default:
      localStorage.setItem(key, JSON.stringify(value));
      break;
  }
}
/**
 * 获取用户缓存
 * @param {*} key
 * @param {*} type
 */
function getUserCache(key, type = 'local') {
  const id = getCache('userId', 'session');
  if (!id) {
    console.error('无法获取用户信息!');
    return;
  }
  return getCache(`${id}-${key}`, type);
}
/**
 * 设置用户缓存
 * @param {*} key
 * @param {*} value
 * @param {*} type
 */
function setUserCache(key, value, type = 'local') {
  const id = getCache('userId', 'session');
  if (!id) {
    console.error('无法获取用户信息!');
    return;
  }
  return setCache(`${id}-${key}`, value, type);
}
function removeCookies(key) {
  key && Cookie.remove(key);
}
export default {
  getCache,
  setCache,
  getUserCache,
  setUserCache,
  removeCookies
};

以上设计属于框架层,提供操作本地存储的能力,但是为什么业务侧需要封装hooks呢?

主要原因:

使用起来有点麻烦,需要import引入工具库,但是hooks使用也需要import引入,因为功能页面大部分引入的都是hooks,使用解构,代码量就会缩减,而且使用认知会减少,引入hooks即可,“你需要用到的都在hooks里面”

Hooks设计方式

那我们开始设计

useSessionStorage.js

import { ref, Ref, isRef, watch as vueWatch } from "vue";
const storage = sessionStorage;
const defaultOptions = {
    watch: true
}
/**
 * 获取数据类型
 * @param defaultValue
 * @returns
 */
const getValueType = (defaultValue) => {
  return defaultValue == null
    ? "any"
    : typeof defaultValue === "boolean"
    ? "boolean"
    : typeof defaultValue === "string"
    ? "string"
    : typeof defaultValue === "object"
    ? "object"
    : Array.isArray(defaultValue)
    ? "object"
    : !Number.isNaN(defaultValue)
    ? "number"
    : "any";
};
/**
 * 按照类型格式数据的常量Map
 */
const TypeSerializers = {
  boolean: {
    read: (v) => (v != null ? v === "true" : null),
    write: (v) => String(v),
  },
  object: {
    read: (v) => (v ? JSON.parse(v) : null),
    write: (v) => JSON.stringify(v),
  },
  number: {
    read: (v) => (v != null ? Number.parseFloat(v) : null),
    write: (v) => String(v),
  },
  any: {
    read: (v) => (v != null && v !== "null" ? v : null),
    write: (v) => String(v),
  },
  string: {
    read: (v) => (v != null ? v : null),
    write: (v) => String(v),
  },
};
/**
 * 缓存操作
 */
const useSessionStorage = (key, initialValue, options) => {
  const { watch } = { ...defaultOptions, ...options };
  const data = ref(null);
  try {
    if (initialValue !== undefined) {
      data.value = isRef(initialValue) ? initialValue.value : initialValue;
    } else {
      data.value = JSON.parse(storage.getItem(key) || "{}");
    }
  } catch (error) {
    console.log(error, "useLocalStorage初始化失败");
  }
  const type = getValueType(data.value);
  // 判断类型取格式化方法
  let serializer = TypeSerializers[type];
  const setStorage = () => storage.setItem(key, serializer.write(data.value));
  // 状态监听
  if (watch) {
    vueWatch(
      data,
      (newValue) => {
        if (newValue === undefined || newValue === null) {
          storage.removeItem(key);
          return;
        }
        setStorage();
      },
      {
        deep: true,
      }
    );
  }
  setStorage();
  return data;
};
export default useSessionStorage;

简介:

useSessionStorage接受一个key和一个value,导出一个响应式的state, 用户直接赋值state.value可自动修改本地sessionStorage。

注意点

  • 不设置value可用于获取本地sessionStorage 例:useSessionStorage('useSessionStorage')
  • value等于undefined或者null可用于删除本地Storage 例:state.value = undefined;

Api

const state = useSessionStorage(
  key: string,
  initialValue?: any,
  options?: Options
);

Params

参数 说明 类型 默认值
key sessionStorage存储键名 any -
initialValue 初始值 any {}
options 配置 Options -

Options

参数 说明 类型 默认值
watch 是否实时修改sessionStorage boolean true

Result

参数 说明 类型
state 可以被修改的数据源 Ref

总结:

这种使用方式,是针对业务侧vue3的,自带响应式绑定,和使用 Ref一样,利用.value进行获取和赋值。

以上就是业务层hooks封装useSessionStorage实例详解的详细内容,更多关于hooks封装useSessionStorage的资料请关注我们其它相关文章!

(0)

相关推荐

  • React函数组件useContext useReducer自定义hooks

    目录 一.hooks(useContext) 二.hooks(useReducer) 三.hooks(useContext搭配useReducer使用) 四.自定义hooks 一.hooks(useContext) 接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值.当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定. 新建useContext.js

  • ahooks封装cookie localStorage sessionStorage方法

    目录 引言 cookie localStorage/sessionStorage 总结与归纳 引言 本文是深入浅出 ahooks 源码系列文章的第九篇,这个系列的目标主要有以下几点: 加深对 React hooks 的理解. 学习如何抽象自定义 hooks.构建属于自己的 React hooks 工具库. 培养阅读学习源码的习惯,工具库是一个对源码阅读不错的选择. 今天来看看 ahooks 是怎么封装 cookie/localStorage/sessionStorage 的. cookie ah

  • vue项目嵌套iframe实现发送、接收数据

    目录 vue嵌套iframe发送.接收数据 vue中iframe的使用 获取iframe里面的内容 CDM跨域 vue嵌套iframe发送.接收数据 <template>     <div class="home">         <iframe src="http://127.0.0.1:8888/index.html" class="mapFrame" ref="mapFrame">&

  • ahooks useRequest源码精读解析

    目录 前言 架构图 源码解析 Fetch onBefore onRequest onSuccess onFinally onError 其它 API 小结 plugins usePollingPlugin useRetryPlugin 小结 useRequest 对自定义 hook 的思考 总结 前言 自从 React v16.8 推出了 Hooks API,前端框架圈并开启了新的逻辑复用的时代,不再需要在意 HOC 的无限套娃导致性能差的问题,也解决了 mixin 的可阅读性差的问题.当然对于

  • ahooks解决React闭包问题方法示例

    引言 本文是深入浅出 ahooks 源码系列文章的第三篇,这个系列的目标主要有以下几点: 加深对 React hooks 的理解. 学习如何抽象自定义 hooks.构建属于自己的 React hooks 工具库. 培养阅读学习源码的习惯,工具库是一个对源码阅读不错的选择. 注:本系列对 ahooks 的源码解析是基于 v3.3.13.自己 folk 了一份源码,主要是对源码做了一些解读,可见 详情. 系列文章: 大家都能看得懂的源码 ahooks 整体架构篇 如何使用插件化机制优雅的封装你的请求

  • 业务层hooks封装useSessionStorage实例详解

    目录 封装原因: 建议: 工具库封装模式: 工具库目录: API设计: 代码实践: Hooks设计方式 useSessionStorage.js 简介: 注意点 Api Params Options Result 总结: 封装原因: 名称:useSessionStorage 功能开发过程中,需要进行数据的临时存储,正常情况下,使用localStorage或者 sessionStorage,存在于 window 对象中,使用场景不一样. sessionStorage的生命周期是在浏览器关闭前,浏览

  • SpringBoot学习系列之MyBatis Plus整合封装的实例详解

    前言 MyBatis-Plus是一款MyBatis的增强工具(简称MP),为简化开发.提高效率,但我们并没有直接使用MP的CRUD接口,而是在原来的基础上封装一层通用代码,单表继承我们的通用代码,实现了单表的基础get.save(插入/更新).list.page.delete接口,使用Vo去接收.传输数据,实体负责与数据库表映射. 这样做的目的是与我们之前的那套jpa保持编码风格上的一致,当我们的通用接口不能满足要求时,应当先考虑使用MP的Service层CRUD接口,然后是Mapper的接口,

  • Android Intent封装的实例详解

    Android Intent封装的实例详解 什么是Intent: Intent是协调应用间.组件之间的通讯和交互.通过Intent你可以启动Activity.Service.Broadcasts.更可以跨程序调用第三方组件.例如:启动拨打电话界面.音乐播放等. 组件     启动 Activity startActicity() Service startService(),bindService( ) Broadcasts sendBroadcast() 使用Intent: 栗子:在一个Act

  • 移动端滑动切换组件封装 vue-swiper-router实例详解

    具体代码如下所述: <strong>组件部分</strong> <template> <div class="main"> <div class="page-tab"> <div :class="nowPath == item.path ? 'tab-item tab-item_active' : 'tab-item'" v-for='(item, index) in tabLis

  • Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解

    本文实例讲述了Zend Framework教程之响应对象的封装Zend_Controller_Response用法.分享给大家供大家参考,具体如下: 概述 响应对象逻辑上是请求对象的搭档.目的在于收集消息体和/或消息头,因而可能返回大批的结果. Zend_Controller_Response响应对象的基本实现 ├── Response │   ├── Abstract.php │   ├── Cli.php │   ├── Exception.php │   ├── Http.php │  

  • Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解

    本文实例讲述了Zend Framework教程之请求对象的封装Zend_Controller_Request方法.分享给大家供大家参考,具体如下: 概述 请求对象是在前端控制器,路由器,分发器,以及控制类间传递的简单值对象.请求对象封装了请求的模块,控制器,动作以及可选的参数,还包括其他的请求环境,如HTTP,CLI,PHP-GTK. 请求对象的基本实现 ├── Request │   ├── Abstract.php │   ├── Apache404.php │   ├── Exceptio

  • JS面向对象编程基础篇(二) 封装操作实例详解

    本文实例讲述了JS面向对象编程封装操作.分享给大家供大家参考,具体如下: Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类). 那么,如果我们要把"属性"(property)和"方法"(method),封装成一个对象,甚至要从原型对象生成一个实例对象,我们应该怎么做呢? 封装 一. 生成实例对象的原始模式 假定我们把猫看成一个对象,

  • IOS 照片编辑的view封装的实例详解

    IOS 照片编辑的view封装 该控件有旋转,缩放,拖动,剪裁的功能,封装成了一个ImageCropperView类 需要导入的库:QuartzCore.framework ImageCopperView.h #import <UIKit/UIKit.h> @protocol ImageCropperDelegate; @interface ImageCropperView : UIView { UIImageView *imageView; id <ImageCropperDelega

  • SpringBoot接口返回结果封装方法实例详解

    rest接口会返回各种各样的数据,如果对接口的格式不加约束,很容易造成混乱. 在实际项目中,一般会把结果放在一个封装类中,封装类中包含http状态值,状态消息,以及实际的数据.这里主要记录两种方式:(效果如下) 1.采用Map对象作为返回对象. /** * Http请求接口结果封装方法 * * @param object 数据对象 * @param msgSuccess 提示信息(请求成功) * @param msgFailed 提示信息(请求失败) * @param isOperate 是否操

  • 公共Hooks封装文件下载useDownloadFile实例详解

    目录 引言 项目环境 封装前提:各方法对比 封装分解:下载核心代码 封装分解:用户体验设计 useDownloadFile.js完整代码 引言 对于经常需要开发企业管理后台的前端开发来说,必不可少的需要使用表格对于数据进行操作,在对于现有项目进行代码优化时,封装一些公共的Hooks. 本篇文章为useDownloadFile.js 基于个人项目环境进行封装的Hooks,仅以本文介绍封装Hooks思想心得,故相关代码可能不适用他人 项目环境 Vue3.x + Ant Design Vue3.x +

随机推荐