【超详细】vue3+pinia+自动持久化插件+自定义存储器对象实现状态数据持久化

本文详细介绍了如何在Vue3中使用Pinia和pinia-plugin-persistedstate插件实现状态数据的自动持久化,包括安装依赖、创建自定义存储器对象、配置store模块以及实际操作和测试。
摘要由CSDN通过智能技术生成

    本文超详细讲解了 vue3+pinia+自动持久化插件+自定义存储器对象实现状态数据持久化 的配置和代码实现,会不会详细得令人发指😄😄😄!
 之前在 vue2 版本中,普遍都是使用 vuex 插件和手写操作 localStorage 或 sessionStorage 的 actions 方法对应用中组件间的共享数据(状态)进行管理。
 由于 vuex 比较臃肿,并且对 TS 支持不够好,vue3 中改为普遍使用 pinia 这个轻量级的状态数据管理插件,该插件也是官方在 vuex 的基础进行优化和修改的,区别是更轻量,性能更好,对 TS 语法的支持较好,并且去除了多余的 Mutations 配置项,直接例用 actions 配置项配置操作 state 数据的方法即可!
 例用 pinia 插件 + 数据持久化插件 pinia-plugin-persistedstate,可以在应用运行中自动持久化 pinia store state 中的数据到浏览器自带本地存储 window.localStorage 和 window.sessionStorage (这两个本地存储器是数据持久化插件 pinia-plugin-persistedstate默认自带支持的),及支持自定义存储器对象,比如本例自定义了一个 cookie 的存储器对象 cookieStorage。
 话不多说,直接入正题!

以下是配置部分:
1、安装所需插件包:pinia、pinia-plugin-persistedstate、js-cookie
npm i pinia pinia-plugin-persistedstate js-cookie
2、在 ./src/store 目录下创建 cookieStorage.js 存储器对象:
// cookieStorage.js
/**
 *  为 pinia-plugin-persistedstate 插件自定义 storage 存储器对象 cookieStorage,
 *  自定义存储器对象,必须按以下要求实现 setItem 和 getItem 方法,并且在这两个方法调用设置/读取 cookie 等
 *  本地存储的方法必须是同步的,不能是异步的,
 *  这里使用 js-cookie 第三方 cookie 操作包实现自定义 storage 存储器对象 cookieStorage
 */
import Cookie from 'js-cookie'

export const cookieStorage = {
    // 参数 key 为 userStore.js 中 persist 配置项中保存到 storage 存储中的 key 键名
    // 参数 state 为 userStore.js 中 persist 配置项中要持久化到 storage 的 state 属性名,不是全部 state
    setItem(key, state) {
        // console.log('cookieStorage setItem state:', state)
        // js-cookie 包 setItem 方法的第三个参数配置对象解释:
        // expires: 为数字时表示过期天数,缺少该参数,表示仅会话期间有效,支持 new Date 对象及其字符串格式
        // path:默认值为/,表示全站点所有路径页面可操作该 cookie,为 '' 空值表示仅当前页面可操作该 cookie
        // domain:缺省该参数默认值为当前域名及其子域名可操作该 cookie
        // return Cookie.setItem(key, state, { expires: 9999, path: '/', domain: '' })
        return Cookie.set(key, state)

    },
    getItem(key) {  // 首次自动加载这个自定义cookie存储器时, getItem 方法比 setItem 方法先执行
        // console.log('cookieStorage getItem:', key, Cookie.get(key))
        let value = Cookie.get(key) || '{}'
        // js-cookie 工具包 get 方法返回字符串,而 vue-cookies 工具包则返回对象
        value = typeof value == 'object' ? value : JSON.parse(value)
        // 存储器的这个 getItem 方法需返回字符串
        return JSON.stringify(value)
    }
}
3、在 ./src/store 目录下创建 userStore.js 操作用户 state 状态数据及方法的 store 模块:
// userStore.js
import { defineStore } from 'pinia'

import { cookieStorage } from '@/store/cookieStorage.js'

/**
 *   在其它页面组件中通过以下方法:
 *   import useUserStore from '@/store/userStore.js'
 *   const userStore = useUserStore()
 *   加载此 userStore 模块后,通过如下方法操作 store
 *   1、通过如下方法读取/设置 state 数据
 *      userStore.user = {xx: 'yy'}
 *      同时设置多个 state 数据方法一(对象参数式):
 *      userStore.$patch({user: {}, age: 20}) 
 *      同时设置多个 state 数据方法二(回调函数式,推荐此方法高性能):
 *      userStore.$patch( (state) => {
 *        state.user = {}
 *        age = 20
 *      })
 *    2、订阅(捕获) state 修改
 *       userStore.$subscribe((mutation, state)
 *    3、订阅(捕获) actions 函数调用
 *       userStore.$onAction(callback, true)  // 参数二 true,表示组件 unmount 后,仍有效,缺省,组件销毁,订阅事件也销毁
 *    4、手动取消订阅 actions 
 *       const unsubscribe = someStore.$onAction(callback)
 *       unsubscribe()
 *    5、可在任意组件中通过 userStore.$hydrate() 方法手动提取保存在 storage 中的数据,应用首次运行时,会自动提取一次
 *    6、应用在运行或刷新页面后,会自动将 store state 中的数据持久化到 storage,也可通过 userStore.$persist() 方法手动持久化,
 *       当修改或通过 actions 修改 state 的数据,才会自动持久化到 storage
 *    更多详细说明见 pinia 官网:https://pinia.vuejs.org/core-concepts/actions.html
 */

export const useUserStore = defineStore('userStore', {
    // 状态数据
    state: () => ({
        user: {},
    }),

    // getters 定义
    geters: {},

    // actions 定义
    actions: {},

    // 自动持久化插件 pinia-plugin-persistedstate 的配置部分,配置单存储对象,用{}即可,多个用数组[]配置
    persist: [
        // sessionStorage 存储配置部分
        {
            // 使用 sessionStorage 本地存储
            storage: window.sessionStorage,
            // 保存到 storage 中数据的 key 键名
            key: 'userInfo',
            // 指定要保存 state 中哪些数据到 storage,默认值为 undefined,和 null 一样默认保存 state 中所有数据,
            // 使用数组指定要保存到 storage 中的数据,如 ['user'],或 ['user.userId'],空数组 [] 表示不保存任何数据,但会自动提取所有数据
            paths: null,
            // 插件在默认自动提取或通过 userStore.$hydrate() 手动拉取 storage 中的数据前,自动触发该回调函数,
            // ctx 是该插件的上下文对象,包括 pinia 实例、该 store 的 state/getters/actions 信息、
            // 和 main.js 里挂载的整个应用的 app 实例信息,beforeRestore 该回调方法在 useUserStore() 方法之前调用,
            // userStore.$hydrate({runHooks: false}),手动提取 store 数据时,加上 {runHooks: false} 参数后,
            // 不会触发 beforeRestore 和 beforeRestore 回调函数
            /* beforeRestore: (ctx) => {
                console.log('piniaPlugPersistedstate beforeRestore ctx:', ctx)
            }, */
            // 插件在默认自动提取或通过 userStore.$hydrate() 手动拉取 storage 中的数据后,自动触发该回调函数,
            // ctx 是该插件的上下文对象,包括 pinia 实例、该 store 的 state/getters/actions 信息、
            // 和 main.js 里挂载的整个应用的 app 实例信息,afterRestore 该回调方法在 useUserStore() 方法之前调用,
            // userStore.$hydrate({runHooks: false}),手动提取 store 数据时,加上 {runHooks: false} 参数后,
            // 不会触发 beforeRestore 和 beforeRestore 回调函数
            /* afterRestore: (ctx) => {
                console.log('piniaPlugPersistedstate afterRestore ctx:', ctx)
            }, */
            // 调试开关,默认值 false。设为 true ,会自动在持久化或提取数据时发生的错误,通过控制台 console.error()打印出来
            debug: true
        },
        // cookieStorage 存储配置部分
        {
            storage: cookieStorage,
            key: 'userInfo',
            paths: undefined,
            debug: true
        }
    ]
})

4、在 main.js 中导入和注册 pinia 插件和数据持久化插件 pinia-plugin-persistedstate
// main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
import { createPinia } from 'pinia'
const pinia = createPinia()
import piniaPersistedState from 'pinia-plugin-persistedstate'
pinia.use(piniaPersistedState)
app.use(pinia)
app.mount('#app')
5、新建 Test.vue 测试 pinia 状态数据及自动持久化操作
// Test.vue
<template>
  <div>
    <div>userStore的数据是(初始化为空):{{ user }}</div>
    <button @click="chgUserData">修改 userStore 数据</button>
  </div>
</template>

<script setup>
// 导入 pinia 配置的 userStore
import { useUserStore } from '@/store/userStore.js'
import { storeToRefs } from 'pinia'

const userStore = useUserStore()
// 解构 userStore.user
const { user } = storeToRefs(userStore)

// 修改 userStore 数据,观察浏览器的本地存储器 sessionStorage 和 cookie 是否同步修改
const chgUserData = () => {
  userStore.$patch({
    user: {
      userId: 888,
      username: 'Samdy_Chan',
      age: 18,
      addr: 'gz',
    },
  })
}
</script>

<style lang="scss" scoped>
</style>
6.1、测试持久化数据同步前

如下图,点击页面的【修改 userStore 数据】按钮前,页面及浏览器本地的 sessionStorage 和 cookie 存储器 userStore 都是为空对象:
在这里插入图片描述

6.2、测试持久化数据同步后

如下图,点击页面的【修改 userStore 数据】按钮后,页面及浏览器本地的 sessionStorage 和 cookie 存储器 userStore 都已经有数据了:
在这里插入图片描述
如下,cookie 存储器中的数据也同步有了,只不过是 cookie 数据默认是通过 urlencoded 编码的
在这里插入图片描述

(完)

觉得好的友友们,别忘了留个脚印和一键三连哦😊😊😊!!!

  • 28
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3和Pinia是一种组合使用的方式,用于实现Vue应用程序的状态管理。Pinia是一个状态管理工具,类似于Vuex,但提供了更简单和更灵活的语法。它支持Vue2和Vue3,并且是类型安全的,支持TypeScript。Pinia可以创建多个全局仓库,而不需要像Vuex那样嵌套模块,使得状态管理的结构更加简单和清晰。相比于Vuex,Pinia的API更少,使用起来更加简单。Pinia的大小仅有1KB,非常轻量级。你可以通过引入Pinia和创建Pinia实例来开始使用Pinia。同时,Pinia还支持数据持久件,可以帮助你实现数据持久存储。你可以在Pinia的官方文档中找到更详细的使用说明和示例代码。\[2\]\[3\] #### 引用[.reference_title] - *1* [一步步打造最新前端框架组合 —— vite+vue3+pinia+vue-router@4+setup+ts](https://blog.csdn.net/jmszl1991/article/details/122825151)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Vue3+Pinia+数据持久 20分钟快速上手](https://blog.csdn.net/zhgweb/article/details/129708483)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值