1. 程式人生 > 其它 >Vue3中pinia使用及狀態持久化儲存

Vue3中pinia使用及狀態持久化儲存

一、pinia基本使用

1.安裝pinia

 npm install pinia

2.main.js註冊

import { createPinia } from 'pinia'

app.use(createPinia())

3.定義store

  建立src/store/index.js

import { defineStore } from 'pinia'
export const useCommentStore = defineStore('comment', {
    // 靜態資料
    state: () => {
        return {
            curCommentlist: []
        }
    },
    
// 相當於計算屬性(有資料快取) getters: { getCurCommentlist(state) { return state.curCommentlist } }, // actions即可以是同步函式也可以是非同步函式 actions: { changeCommentlist(curCommentlist) { this.curCommentlist = curCommentlist }, } })

4.頁面使用

// 引入pinia倉庫
import store from '../stores/index' import { storeToRefs } from 'pinia' const { useLoginStore, useCommentStore } = store const commentStore = useCommentStore() const curUsername = useLoginStore().getCurUsername // 無需賦值操作,getters獲取即可 const { curCommentlist } = storeToRefs(commentStore) // 需要賦值,不能使用getters

二、state修改方式

大致有如下四種修改state狀態值的方式

// 引入pinia倉庫
import { useLoginStore } from '../stores/loginStore.js'
import { storeToRefs } from 'pinia'
const loginStore = useLoginStore()
const { curUsername } = storeToRefs(loginStore)
const router = useRouter()
const formState = reactive({
    username: '',
    password: '',
    remember: true,
});
const onFinish = (values) => {
    const { username } = values
    // localStorage.setItem('username', username) // 改為如下pinia儲存狀態

    // pinia start
    // 方式一:最簡單的方法,如下
    // 解構後更改方式
    curUsername.value = username;
    // 解構前更改方式
    // loginStore.curUsername = username;

    // 方式二:若要同時修改多個數據,建議使用$patch來實現批量更新,在內部做了優化
    // loginStore.$patch({
    //     curUsername: username
    // })

    // 方式三:更好的批量更新方法,通過$patch傳遞一個函式來實現,這裡的state就是useLoginStore容器中的state
    // loginStore.$patch((state) => {
    //     state.curUsername = username
    // });

    // 方式四:通過 actions 來修改資料
    // loginStore.changeCurUsername(username);
    // pinia end

    router.push('/commentOn')
};

三、getters使用及注意事項

  1. 無更改state狀態值操作,getters獲取即可;需要更改state狀態值,不能使用getters
  2. 元件檢視需要更新,應該使用響應式api storeToRefs;檢視無需依賴state更新直接用getters獲取state即可
// pinia 獲取列表
import { storeToRefs } from 'pinia'
import store from '../stores/index.js'
const { useLoginStore, useCommentStore } = store
const curUsername = useLoginStore().getCurUsername // 檢視無需依賴更新使用getters獲取即可
const commentStore = useCommentStore() 
const { curCommentlist } = storeToRefs(commentStore) // 頁面檢視更新需要使用響應式

四、pinia持久化儲存

1.手動利用localStorage或sessionStorage進行儲存

// 不使用pinia-plugin-persist進行持久化操作
// 通過 store 的 $subscribe() 方法檢視狀態及其變化;subscriptions 只會在 patches 之後觸發一次
// useLoginStore().$subscribe((mutation, state) => {
//     // import { MutationType } from 'pinia'
//     mutation.type // 'direct' | 'patch object' | 'patch function'
//     // 與 loginStore.$id 相同
//     mutation.storeId // 'login'
//     // 僅適用於 mutation.type === 'patch object'
//     mutation.payload // 補丁物件傳遞給 to loginStore.$patch()
//     console.log('mutation', mutation);
//     // 每當它發生變化時,將整個狀態持久化到本地儲存
//     localStorage.setItem('login', JSON.stringify(state))
// })

// 1. 儲存資料
const instance = useLoginStore();
instance.$subscribe((_, state) => {
    localStorage.setItem('login-store', JSON.stringify({ ...state }));
});
// 2. 獲取儲存的資料,先判斷有無,無則用先前的
const old = localStorage.getItem('login-store');
if (old) {
    instance.$state = JSON.parse(old);
}

2.利用持久化工具 pinia-plugin-persist

  • 安裝
npm i pinia-plugin-persist --save
  • main.js引入
// 引入pinia倉庫
import { createPinia } from 'pinia'
// 持久化儲存pinia
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist)

const app = createApp(App)

app.use(store)
  • store中的配置引數 persist
import { defineStore } from 'pinia'

export const useLoginStore = defineStore('login', {
    // 靜態資料
    state: () => {
        return {
            token: '',
            curUsername: '',
        }
    },
    persist: {
        enabled: true,
        // 自定義持久化引數
        strategies: [
            {
                // 自定義key
                key: 'login_store',
                // 自定義儲存方式,預設sessionStorage
                storage: localStorage,
                // 指定要持久化的資料,預設所有 state 都會進行快取,可以通過 paths 指定要持久化的欄位,其他的則不會進行持久化。
                paths: ['curUsername'],
            }
        ]
    },
    // 相當於計算屬性(有資料快取)
    getters: {
        getCurUsername(state) {
            return state.curUsername
        },
    },
    // actions即可以是同步函式也可以是非同步函式
    actions: {
        changeCurUsername(curUsername) {
            this.curUsername = curUsername
        },
    }
})