Pinia持久化

Pinia 是Vue的存储库

安装

1、vue3 npm install pinia --save
2、vue2 npm install pinia @vue/composition-api --save

引入

1、vue3 再main.js中

import { createPinia } from 'pinia'
// 创建pinia的实例
const pinia = createPinia();

const app = createApp(App); 
// 挂载到vue的根实例上
app.use(pinia);

2、vue2 在main.js中

import { createPinia, PiniaVuePlugin } from 'pinia'
const pinia = createPinia();        //调用创建pinia
Vue.use(PiniaVuePlugin)

new Vue({
  el: '#app',
  pinia,
  components: { App },
  template: '<App/>'
}).$mount('#app')

在store的文件夹下创建index.js文件

import { defineStore } from 'pinia';
// 1、定义容器
// 参数1:容器的id,必须唯一,将来pinia会把所以的容器挂载根容器
// 参数2: 选项对象
// 返回值: 一个函数,调用得到容器实例
export const useMainStore = defineStore('main',{
    // 类似域组件的data 用来存储全局状态的
    // 1、必须是函数,避免再服务器端渲染的时候避免交叉请求导致的数据状态污染
    // 2、必须是箭头函数,这是为了更好的 ts 类型推导
    state:()=>{
        return {
            count: 100,
            foo:"bar",
            arr:[1,2,3]
        }
    },
    // 类似域组件中的computer 用来封装计算属性,有缓存作用
    getters: {
        // 函数接收一个可选参数:state 状态对象   也可以传 但是不用 
        // count10(state) {
        //     console.log("调用了");
        //     return state.count + 10;
        // }
        // 如果getters中使用了this,则必须手动指定返回值的类型,否则类型推导不出来
        count():number {
            return this.count + 10;
        }
    },
    // 类似域methods 封装业务逻辑,修改state
    actions: {
        changeState(i:number) {
            this.count += i;
            this.foo = "hello";
            this.arr.push(4);
        }
    }
})

页面中使用pinia

1、vue3

import {storeToRefs } from "pinia"
import { useMainStore } from '../store';

const mainStore = useMainStore();
// 这样是有问题的因为这样拿到的数据不是响应式的,是一次的
// pinia 其实就是把state数据做了reactive处理了    
// const { count, foo } = mainStore;

// 把解构处理的数据做ref响应式代理
const { count, foo, arr } = storeToRefs(mainStore);
console.log(mainStore.count)
const handleChangeState = ()=>{
  // 方式一:最简单的方式修改
  // mainStore.count++

  //方式二:如果需要修改多个数据,建议使用 $patch 批量更新
  // mainStore.$patch({
  //   count:mainStore.count + 1,
  //   foo: "hello",
  //   arr: [...mainStore.arr, 4]
  // })

  // 方式三:&patch一个函数  更好的批量更新的方式:&patch一个函数,批量更新
  // mainStore.$patch(state=>{
  //   state.count++
  //   state.foo = "hello"
  //   state.arr.push(4)
  // })

  // 方式四: 逻辑比较多的时候,可以封装到actions中
  mainStore.changeState(10);

2、vue2

import {mapState,mapActions} from 'pinia'
import storeId from '../store'  //storeId就是导出的那个值
export default {
  methods: {
     ...mapActions(storeId,['changeState'])//不把函数补充完整的时候页面会报错
  },
  computed:{
    ...mapState(storeId,['count','foo','arr'])
  }
};

使用Pinia Plugin Persist/pinia-plugin-persistedstate做数据持久化

安装 npm i pinia-plugin-persist
  • 在jsconfig.json中添加
{
  "compilerOptions": {
    "types": [
      "pinia-plugin-persist"
    ]
  },
}
  • 引入
import vueCompositionApi from '@vue/composition-api'
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persist'
import App from './App.vue'

const pinia = createPinia()
pinia.use(piniaPersist)

Vue.use(vueCompositionApi)
Vue.use(pinia)

new Vue({
  pinia,
  render: h => h(App),
}).$mount('#app')
  • 使用
// store/index.js
import Cookies from 'js-cookie'//使用cookies存储的使用要下载依赖

const cookiesStorage: Storage = {
  setItem (key, state) {
    return Cookies.set('accessToken', state.accessToken, { expires: 3 })
  },
  getItem (key) {
    return JSON.stringify({
      accessToken: Cookies.getJSON('accessToken'),
    })
  },
}

export const useUserStore = defineStore('storeUser', {
  state () {
    return {
      firstName: 'S',
      lastName: 'L',
      accessToken: 'xxxxxxxxxxxxx',
    }
  },
  persist: {
    enabled: true,
    strategies: [
      { storage: sessionStorage, paths: ['firstName', 'lastName'] },
      { storage: localStorage, paths: ['accessToken'] },
      {
        storage: cookiesStorage,
        paths: ['accessToken']
      },
    ],
  },
})
安装 npm i pinia-plugin-persistedstate
  • 引入
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
  • 使用
import { defineStore } from 'pinia'
// import { stringify, parse } from 'zipson'   序列化

export const useStore = defineStore('main', s{
  state: () => {
    return {
      msg: 'pinia',
      obj: {
        data: 'hello pinia',
      },
      save: [
        { me: 'saved', ignored: 'ignored' },
        { me: 'saved-too', value: 'ignored-too' },
        { me: 'saved-as-well', test: 'ignored-as-well' },
        ],
    }
  },
  // 所有数据持久化
  // persist: true,
  // 持久化存储插件其他配置
  persist: {
    // 修改存储中使用的键名称,默认为当前 Store的 id
    key: 'storekey',
    // 修改为 sessionStorage,默认为 localStorage
    storage: window.sessionStorage,
    // 部分持久化状态的点符号路径数组,[]意味着没有状态被持久化(默认为undefined,持久化整个状态)
    paths: ['obj.data','save.[].me'],
    // serializer: {//序列化
    //   deserialize: parse,
    //   serialize: stringify
    // },
    beforeRestore: (ctx) => {
      console.log(`about to restore '${ctx.store.$id}'`)
    },
    afterRestore: (ctx) => {
      console.log(`just restored '${ctx.store.$id}'`)
    }
  },
})
posted @   兜兜~  阅读(2609)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示