Vuex持久化插件 您所在的位置:网站首页 vuex插件持久化 Vuex持久化插件

Vuex持久化插件

2023-10-14 21:15| 来源: 网络整理| 查看: 265

前言

用vue开发中大型应用时候,我们通常都会使用vuex进行状态管理,但刷新后刷新后存在内存中的vuex数据将会丢失。在很多场景中,我们不愿意看到这样的结果的。

Vuex 社区中有相关的解决方案,比如vue-savedata,vuex-persistedstate,解决思路都是state里的数据保存一份到本地存储(localStorage、sessionStorage、cookie)中。

实现插件之前,先看下怎么实现一个简单的插件

写个 Vuex 插件

Vuex 的 store 接受 plugins 选项,这个选项暴露出每次 mutation 的钩子。Vuex 插件就是一个函数,它接收 store 作为唯一参数:

const myPlugin = store => { // 当 store 初始化后调用 store.subscribe((mutation, state) => { // 每次 mutation 之后调用 // mutation 的格式为 { type, payload } }) }

使用:

const store = new Vuex.Store({ // ... plugins: [myPlugin] })

store.subscribe : 订阅 store 的 mutation。handler 会在每个 mutation 完成后调用,接收 mutation 和经过 mutation 后的状态作为参数

实现一个简单的Vuex持久缓存插件

缺点:vuex 中所有的state全部保存在本地storage中,并且每次触发mutation,都会储存state。如果频繁操作vuex,会一直更新storage,性能太差

export default (options = {}) => { return store => { store.replaceState(JSON.parse(window.localStorage.cacheStore)) store.subscribe((mutation,state) => { window.localStorage.setItem('cacheStore',JSON.stringify(state)) }) } } 设计一个完整的Vuex持久缓存插件 实现代码 export default (options = {}) => { /** cache:缓存列表 delay:防抖或节流时间 mode:防抖或节流(debounce|throttle )自行实现吧(^_^) */ let {cache = [],delay = 1000,mode='debounce'} = options // 缓存的数据 let cacheData = {} // 本地储存辅助函数 mode:缓存模式 const storeage = (mode = "LS") => { if(mode.toUpperCase() == 'SS') { return window.sessionStorage } return window.localStorage } // 防抖函数 const debounce = (fn, delay) => { let timer = null; let status = true; return function () { let args = arguments; if (timer) clearTimeout(timer) timer = setTimeout(() => fn.apply(this, args), delay) } } // 判断是否对象 const isObject = value => Object.prototype.toString.call(value) == "[object Object]" // 合并对象 const merge = (a,b) => { for (var key in b) { if (!a.hasOwnProperty(key)) { a[key] = b[key]; } else if (isObject(b[key]) && isObject(a[key])) { merge(a[key], b[key]); } } return a; } // 窗口关闭触发更新本地storeage的数据 window.addEventListener('beforeunload',() => { Object.keys(cacheData).forEach(key => { let {mode,...other} = cacheData[key] storeage(mode).setItem(key,JSON.stringify(other)) }) },false) return store => { let {state:initState,_modulesNamespaceMap} = store // 判断是否模块 const hasModule = name => !!_modulesNamespaceMap[name+'/'] let data = cache.reduce((prev,curr) => { let {key,mode} = curr if(hasModule(key) && storeage(mode)[key]){ prev[key] = JSON.parse(storeage(mode)[key]).data }else{ // Root state // 需要的可以自行扩展 // code } return prev },{}) //合并本地storeage中的数据到Vuex state 中,并初始化 merge(data,initState) store.replaceState(data) store.subscribe(debounce((mutation,state) => { let [key,type] = mutation.split('/') // 是否模块 if(type && hasModule(key)){ let findItem = cache.find(option => option.key === key) //是否缓存 if(findItem){ let {whiteList,mode} = findItem // 是否在缓存白名单中 if(whiteList && !whiteList.includes(type) || !whiteList){ let module = state[key] cacheData[key] = { mode, data:module } } } }else{ // Root state // 需要的可以自行扩展 // code } },delay)) } } 使用插件 import CachePlugin from './vuex-cache-plugin' const store = new Vuex.Store({ modules:{ saveData:{ namespaced:true }, saveData2:{ namespaced:true } } plugins: [ CachePlugin({ delay:1000, cache:[ {key:'saveData',mode:'SS'} {key:'saveData2',whiteList:['SET_TEST']} ] }) ] })


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有