关于vuex的缓存持久实践

前言

在现代前端开发中,状态管理是构建复杂应用的关键环节。Vuex作为Vue.js的官方状态管理库,为我们提供了集中式的状态管理方案。然而,Vuex存在一个明显的痛点:页面刷新后状态会重置,这给用户体验带来了不小的挑战。

本文将详细介绍如何使用vuex-persistedstate插件实现Vuex状态的持久化缓存,确保用户在刷新页面后仍能保持登录状态、菜单信息、用户偏好设置等重要数据

为什么需要Vuex持久化?

在单页应用(SPA)中,Vuex的状态存储在内存中,当页面刷新时,这些状态会被重置。这意味着:

  • 用户登录状态可能丢失,需要重新登录
  • 用户的权限菜单和偏好设置无法保存
  • 用户的操作填写进度丢失等

为了解决这些问题,我们需要将Vuex状态持久化到浏览器的存储中(如sessionStorage、localStorage)。

实践过程

1. 安装与基础配置

首先安装依赖:

bash

csharp 复制代码
npm install vuex-persistedstate
# 或
yarn add vuex-persistedstate

2. 创建持久化插件

以下是我们在项目中实际使用的配置:

js 复制代码
import createPersistedState from 'vuex-persistedstate'
import { getToken } from '@/utils/auth'

export const PERSISTEDSTATE_KEY = 'project-app-store'

/**
 * 清除持久化数据
 */
export function clearPersistedState() {
  window.sessionStorage.removeItem(PERSISTEDSTATE_KEY)
}

const persistedStatePlugin = createPersistedState({
  key: PERSISTEDSTATE_KEY,
  storage: {
    getItem(key) {
      if (hasPersistedData()) {
        return sessionStorage.getItem(key)
      }
      return JSON.stringify({
        user: {
          token: getToken()
        },
        menu: {}
      })
    },
    setItem(key, value) {
      sessionStorage.setItem(key, value)
    },
    removeItem(key) {
      sessionStorage.removeItem(key)
    }
  },
  reducer(state) {
    return {
      user: state.user,
      menu: state.menu
    }
  }
})

export default persistedStatePlugin

// 检查本地是否有缓存
export function hasPersistedData() {
  try {
    const persisted = sessionStorage.getItem(PERSISTEDSTATE_KEY)
    if (persisted) {
      const parsed = JSON.parse(persisted)
      // 检查是否有有效的 token 数据
      return !!parsed.user?.token
    }
  } catch (e) {
    console.warn('Failed to check persisted data:', e)
    return false
  }
  return false
}

3. 在Vuex中引入插件

在store的配置文件中引入我们创建的持久化插件:

js 复制代码
import Vue from 'vue'
import Vuex from 'vuex'
....
import persistedStatePlugin from './plugins/persistedstate'

Vue.use(Vuex)

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

export default store

配置详解

1. 存储键名(key)

js 复制代码
key: PERSISTEDSTATE_KEY

这里我们定义了存储的键名,避免与其他应用产生冲突

2. 自定义存储处理

javascript 复制代码
storage: {
  getItem(key) {
    if (hasPersistedData()) {
      return sessionStorage.getItem(key)
    }
    return JSON.stringify({
      user: {
        token: getToken()
      },
      menu: {}
    })
  },
  setItem(key, value) {
    sessionStorage.setItem(key, value)
  },
  removeItem(key) {
    sessionStorage.removeItem(key)
  }
}

这里的特殊处理是因为缓存插件开启后,不管有没有本地缓存,都会覆盖store初始化的值,所以需要特殊处理一下,以免token的初始值丢失(本项目token由后端登录鉴权接口写入cookie中,接口调用时,将access_token放在请求头里,request封装axios在store里获取)

3. 状态选择器(reducer)

javascript 复制代码
reducer(state) {
  return {
    user: state.user,
    menu: state.menu
  }
}

通过reducer函数,我们可以选择性地持久化部分状态,避免将敏感或不必要的数据持久化。

4. 工具函数

我们还提供了一些工具函数来增强插件的可用性:

javascript 复制代码
// 检查是否存在有效的持久化数据
export function hasPersistedData() {
  try {
    const persisted = sessionStorage.getItem(PERSISTEDSTATE_KEY)
    if (persisted) {
      const parsed = JSON.parse(persisted)
      return !!parsed.user?.token
    }
  } catch (e) {
    console.warn('Failed to check persisted data:', e)
    return false
  }
  return false
}

// 清除持久化数据 在用户登录过期或退出登录时调用
export function clearPersistedState() {
  window.sessionStorage.removeItem(PERSISTEDSTATE_KEY)
}

进一步优化建议

  1. 可以考虑添加数据加密功能,增强安全性
  2. 对于大型应用,可以引入状态版本管理机制

如果你有更好的实践方案或建议,欢迎在评论区分享讨论!

相关推荐
西陵4 分钟前
为什么说 AI 赋能前端开发,已经不是选择题,而是必然趋势?
前端·架构·ai编程
by__csdn1 小时前
Vue3 setup()函数终极攻略:从入门到精通
开发语言·前端·javascript·vue.js·性能优化·typescript·ecmascript
天天扭码1 小时前
前端如何实现RAG?一文带你速通,使用RAG实现长期记忆
前端·node.js·ai编程
Luna-player2 小时前
在前端中,<a> 标签的 href=“javascript:;“ 这个是什么意思
开发语言·前端·javascript
lionliu05192 小时前
js的扩展运算符的理解
前端·javascript·vue.js
小草cys2 小时前
项目7-七彩天气app任务7.4.2“关于”弹窗
开发语言·前端·javascript
奇舞精选2 小时前
GELab-Zero 技术解析:当豆包联手中兴,开源界如何守住端侧 AI 的“最后防线”?
前端·aigc
奇舞精选2 小时前
Vercel AI SDK:构建现代 Web AI 应用指南
前端·aigc
神仙别闹3 小时前
基于C语言实现B树存储的图书管理系统
c语言·前端·b树
玄魂3 小时前
如何查看、生成 github 开源项目star 图表
前端·开源·echarts