pinia-plugin-persist 解决刷新后,store数据重置

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态

在某些特定的单页面应用场景下,我们使用常规的 store 来存储数据,很多时候面临着刷新就会被重置,所以,我们急需 pinia-plugin-persist 来实现对某些特定的数据进行状态保持

npm i pinia-plugin-persist

Vue3 main.ts- 配置

import {
    
     createApp } from 'vue'
import {
    
     createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persist'

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

createApp({
    
    })
  .use(pinia)
  .mount('#app')

Typescript definitions tsconfig.json - 配置

{
    
    
  "compilerOptions": {
    
    
    "types": [
      "pinia-plugin-persist"
    ]
  },
}

/store/index.js - 定义

export const useUserStore = defineStore('storeUser', {
    
    
  state () {
    
    
    return {
    
    
      firstName: 'S',
      lastName: 'L',
      accessToken: 'xxxxxxxxxxxxx',
    }
  },
  persist: {
    
    
    enabled: true,
    strategies: [
      {
    
    
        key: 'accessToken',  //自定义 Key值
        storage: localStorage,  // 选择存储方式
		paths: ['accessToken']  // state 中的字段名,按组打包储存
		// assessToken,数据不为空时localStorage才会去存储,数据为空时,不会去存储()
      },
    ],
  },
})


使用

<template>
  <button @click="onButton">点击增加</button>
</template>
<script lang="ts" setup>
import store from '@/store'
const appStore = store.useUserStore()
// computed 可以获取响应式数据
const assessToken = computed(() => {
    
     appStore.accessToken })
const onButton = () => {
    
    
  console.log(assessToken)
}
</script>
<style lang="scss" scoped></style>

源码解读

type Store = PiniaPluginContext['store'];
type PartialState = Partial<Store['$state']>;

export const updateStorage = (strategy: PersistStrategy, store: Store) => {
    
    

  // 默认使用 sessionStorage
  const storage = strategy.storage || sessionStorage
  
  // 默认存储 key 为 store.$id
  const storeKey = strategy.key || store.$id

  if (strategy.paths) {
    
    
  
    // 遍历 paths 将对应的属性收集到 finalObj 中
    const partialState = strategy.paths.reduce((finalObj, key) => {
    
    
      finalObj[key] = store.$state[key]
      return finalObj
    }, {
    
    } as PartialState)
    
    // 执行存储
    storage.setItem(storeKey, JSON.stringify(partialState))
  } else {
    
    
  
    // 如果没有 paths,则按整个 store.$state 存储
    storage.setItem(storeKey, JSON.stringify(store.$state))
  }
}


export default ({
    
     options, store }: PiniaPluginContext): void => {
    
    

  // 判断插件功能是否开启
  if (options.persist?.enabled) {
    
    
  
    // 默认策略实例
    const defaultStrat: PersistStrategy[] = [{
    
    
      key: store.$id,
      storage: sessionStorage,
    }]

    const strategies = options.persist?.strategies?.length ? options.persist?.strategies : defaultStrat

    strategies.forEach((strategy) => {
    
    
      const storage = strategy.storage || sessionStorage
      const storeKey = strategy.key || store.$id
      const storageResult = storage.getItem(storeKey)

      if (storageResult) {
    
    
      
        // 如果 storage 中存在同步数据
        store.$patch(JSON.parse(storageResult))
        updateStorage(strategy, store)
      }
    })

    store.$subscribe(() => {
    
    
    
      // 监听 state 变化,同步更新 storage
      strategies.forEach((strategy) => {
    
    
        updateStorage(strategy, store)
      })
    })
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_55042716/article/details/129840886
今日推荐