• vue 数据持久化(刷新保存数据)的探索


    对于 PC 端的 VUE 项目来讲,刷新页面导致数据消失是一个绕不开的坑。好在 vuex-persistedstate插件能够解决这个问题。

    vuex-persistedstate

    它的原理是:

    • 每次 mutation 都将整个 store 保存到本地(localStorage/sessionStorage/cookie);
    • 初始化时用本地数据替换(replaceState)掉 store。

    它的代码简洁、逻辑清晰,且对业务代码毫无侵入,可以说是我辈楷模。(剧终...

    今天,咱就鸡蛋里挑骨头,站在个人的角度上主观的评评这个方案的缺点。

    第一:和 Vuex 绑定,对于大多数项目来说,用 Vuex 基本上是白白增加复杂度。

    第二:对于超大型项目来讲,频繁的快照整个 store ,可能会有性能消耗。

    第三:需要我们关注什么时候删除本地数据。

    那么,有没有其他的可替代方案呢?

    onbeforeunload

    新的方案,个人觉得应该做到:

    • 不强制,需要才导入
    • 只在关键时刻才保存,这个时机就是页面刷新的那一刻
    • 不依赖除 Vue 外的任何库/框架

    经过一番折腾,有了下面的代码 saveBeforeUnload.mixin.js

    import Store from "@/utils/sessionStorage";
    const CACHE_PREFIX = "CACHE_KEY_";
    const getCacheKey = path => CACHE_PREFIX + path;
    
    export default {
      created() {
        const CACHE_KEY = getCacheKey(this.$route.path);
        const CACHE_DATA = Store.get(CACHE_KEY);
        if (CACHE_DATA) {
          Object.assign(this, CACHE_DATA);
          Store.remove(CACHE_KEY);
        }
      },
    
      beforeRouteEnter(to, from, next) {
        next(vm => {
          window.onbeforeunload = () => {
            const CACHE_KEY = getCacheKey(vm.$route.path);
            Store.set(CACHE_KEY, vm.$data);
            window.onbeforeunload = null;
          };
        });
      },
    };
    

    从文件名可以看出,它其实是一个 mixin,需要在页面中导入。这段代码有如下缺陷:

    • 刷新时,只能保存当前这个页面的数据,如果多个页面都 mixin 了,其他页面的数据不会被保存
    • 由于是 mixin 方式,对业务代码有些许侵入但不影响运行

    进化版

    如果想要保存多个页面的数据,需要将代码做如下更改:

    import Store from "@/utils/sessionStorage";
    const CACHE_PREFIX = "CACHE_KEY_";
    const getCacheKey = path => CACHE_PREFIX + path;
    
    const handler = {};
    
    export default {
      created() {
        const CACHE_KEY = getCacheKey(this.$route.path);
        const CACHE_DATA = Store.get(CACHE_KEY);
        if (CACHE_DATA) {
          Object.assign(this, CACHE_DATA);
          Store.remove(CACHE_KEY);
        }
      },
    
      beforeRouteEnter(to, from, next) {
        next(vm => {
          const CACHE_KEY = getCacheKey(vm.$route.path);
          if (handler[CACHE_KEY]) return;
    
          handler[CACHE_KEY] = () => {
            Store.set(CACHE_KEY, vm.$data);
          }
          window.addEventListener('beforeunload', handler[CACHE_KEY]);
        });
      },
    
      destroyed() {
        const CACHE_KEY = getCacheKey(this.$route.path);
        if (handler[CACHE_KEY]) {
          window.addEventListener("beforeunload", handler[CACHE_KEY]);
          handler[CACHE_KEY] = null;
        }
      }
    };
    
    export function removeCachedData(location) {
      Store.remove(getCacheKey(location.path));
    }
    
    

    并在每次路由 push/replace 时,删除 CACHE_KEY 对应的本地数据,防止旧数据被渲染。

    const __push = router.push;
    router.push = (location, ...args) => {
      if (typeof location === 'string') {
        location = {
         path: location
        }
      }
    
      removeCachedData(location);
      __push(location, ...args);
    }
    
  • 相关阅读:
    解决 CAS + Spring Security整合 无法获取当前登录用户信息
    开发帮助网址收藏
    删除maven最近导入失败的文件
    二、maven的下载和安装配置
    一、maven的介绍
    数据结构学习笔记
    java网络URL请求编程入门
    Python学习(三)
    Python学习(二)
    EasyUI入门
  • 原文地址:https://www.cnblogs.com/fayin/p/13039176.html
Copyright © 2020-2023  润新知