当前位置 : 主页 > 网络编程 > JavaScript >

业务层hooks封装useSessionStorage实例详解

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 封装原因: 建议: 工具库封装模式: 工具库目录: API设计: 代码实践: Hooks设计方式 useSessionStorage.js 简介: 注意点 Api Params Options Result 总结: 封装原因: 名称:useSessionStorag
目录
  • 封装原因:
    • 建议:
  • 工具库封装模式:
    • 工具库目录:
  • 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

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

    Options

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

    Result

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

    总结:

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

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

    上一篇:vue-router中关于children的使用方法
    下一篇:没有了
    网友评论