一.vuex数据持久化存储
这里使用的是vuex@4.1.0版本,和之前的vuex@3一样,数据持久化存储方案也使用 vuex-persistedstate,版本是最新的安装版本,当前可下载依赖包版本4.1.0,接下来在vue3项中安装和使用:
安装vuex-persistedstate
npm i vuex-persistedstate --save 或者 yarn add vuex-persistedstate
使用vuex-persistedstate
src/stores/index.ts
import { createStore } from 'vuex'
import moduleTest from './modules/moduleTest'
import createPersistedState from 'vuex-persistedstate'import vuexPersistTest from './vuexPersistTest'
// 创建一个新的 store 实例
export default createStore({state () {return {sum: 0,hell: 'hello world'}},mutations: {// 负责修改state中的count值sumMutations (state, newVal) {state.sum += newVal}},actions: {sumActions ({ commit }, params) {// 触发mutations中的countMutations函数并传递参数setTimeout(()=>{commit("sumMutations", params)},300)}},getters: {getSum: state => state.sum},modules: {moduleTest,vuexPersistTest},plugins: [ createPersistedState({storage: sessionStorage,paths: ["vuexPersistTest.sum","vuexPersistTest.nameList","sum","hell"],key: "createPersistedState"}), createPersistedState({storage: localStorage,paths: ["vuexPersistTest.count"],key: "createPersistedState"}) ],
})
在main.js使用store
import { createApp } from 'vue'
import store from './stores'import App from './App.vue'
import router from './router'import './assets/main.css'createApp(App).use(store).use(router).mount('#app')
简单分析createPersistedState
plugins: [ // 可以多组createPersistedState实例使用createPersistedState({storage: sessionStorage,// 模块vuexPersistTest中有sum 和 nameList字段paths: ["vuexPersistTest.sum","vuexPersistTest.nameList","sum","hell"],key: "createPersistedState"}), createPersistedState({// 存储类型storage: localStorage,// 需要持久化的state属性paths: ["vuexPersistTest.count"],// 存储的keykey: "createPersistedState"}) ],
createPersistedState可配置属性:
key <String>:用于存储持久状态的密钥。默认为vuex。
paths <Array>:任何路径的数组,以部分保留状态。如果未给出路径,则完整状态将保留。如果给定一个空数组,则不会保留任何状态。必须使用点表示法指定路径。如果使用模块,请包括模块名称。例如:“ auth.user”默认为undefined。
reducer <Function>:将根据给定路径调用以减少状态持久化的函数。默认值包括这些值。
subscriber <Function>:一个用于设置突变订阅的函数。默认为store => handler => store.subscribe(handler)。
storage <Object>:代替(或结合)getState和setState。默认为localStorage。
getState <Function>:将被调用以恢复先前持久状态的功能。默认使用storage。
setState <Function>:将被调用以保持给定状态的函数。默认使用storage。
filter <Function>:一个将被调用以过滤setState最终将在存储中触发的任何突变的函数。默认为() => true。
overwrite <Boolean>:补液时,是否getState直接用输出结果覆盖现有状态,而不是用合并两个对象deepmerge。默认为false。
arrayMerger <Function>:补充状态时合并数组的功能。默认为function (store, saved) { return saved }(保存状态替换提供状态)。
rehydrated <Function>:补液完成后将被调用的函数。当您使用Nuxt.js时,该功能非常有用,持久化状态的恢复是异步发生的。默认为store => {}
fetchBeforeUse <Boolean>:一个布尔值,指示在使用插件之前是否应从存储中获取状态。默认为false。
assertStorage <Function>:确保插件可用的可重写功能,会在插件初始化时触发。默认情况下,是在给定的Storage实例上执行Write-Delete操作。请注意,默认行为可能会引发错误(如DOMException: QuotaExceededError)
store/modules/vuexPersistTest.ts模块作为定义state属性用来测试持久化
export default { state: { sum: 0,count: 100,nameList: ["张三","李四"]}, mutations: { updateSum (state:any,newVal:number) {state.sum = newVal},updateCount (state:any,newVal:number) {state.count = newVal},updateNameList (state:any, newVal:string[]) {state.nameList = newVal},}, actions: { }, modules: { }
}
在views/test.vue 测试,运行页面操作状态属性修改
<script setup lang="ts">import { computed,ref } from 'vue'import { useStore} from 'vuex'const {commit,dispatch,state,getters,actions} = useStore();// 数据持久化const getPersistTestSum = computed(()=> state.vuexPersistTest.count)const updatePersistTestSum = () => {commit('updateSum',state.vuexPersistTest.sum+1)}const updatePersistTestCount = () => {commit('updateCount',state.vuexPersistTest.count+1)}const updatePersistTestName = () => {commit('updateNameList',['更新数据中...'])}
</script><template><main><div style="margin-bottom:20px"><button @click="updatePersistTestSum">改变sum</button>{{ state.vuexPersistTest.sum }}<br><button @click="updatePersistTestCount">改变count</button>{{ state.vuexPersistTest.count }}<br><button @click="updatePersistTestName">改变nameList</button>{{ state.vuexPersistTest.nameList }}<br></main>
</template>
二.pinia数据持久化存储
pinia持久化官方推荐使用使用pinia-plugin-persist插件处理持久化存储问题,具体参考:
https://seb-l.github.io/pinia-plugin-persist/#install
安装pinia-plugin-persist
npm install pinia-plugin-persist 或者 yarn add pinia-plugin-persist
在入口文件main.ts引入
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persist'import App from './App.vue'
import router from './router'const pinia = createPinia()
pinia?.use(piniaPersist)createApp(App).use(pinia).use(store).use(router).mount('#app')
src/stores/piniaPersistTest.ts 新建一个测试模块
import { defineStore } from "pinia";
import { ref } from "vue";
import Cookies from "js-cookie";// 对象写法
export const usePersistTest1 = defineStore("storePersist", {state: () => {return {firstName: "S",lastName: "L",accessToken: "xxxxxxxxxxxxx",count: 100,};},actions: {setToken(value: string) {this.accessToken = value;},},persist: {// 开启持久存储enabled: true,// 指定哪些state的key需要进行持久存储// storage默认是 sessionStorage存储// paths需要持久存储的keystrategies: [{ storage: localStorage, paths: ["accessToken"] },{ storage: sessionStorage, paths: ["firstName", "lastName"] },],},
});// 函数写法
export const usePersistTest = defineStore("storePersist",() => {const firstName = ref("S");const lastName = ref("L");const accessToken = ref("XXXXXXXX");const count = ref(100);return {firstName,lastName,accessToken,count,};},{persist: {// 开启持久存储 开启 enabled 之后,默认会对整个 Store 的 state 内容进行 sessionStorage 储存enabled: true,// 自定义存储的 key,默认是 store.$id// key: "custom storageKey",// 指定哪些state的key需要进行持久存储// storage默认是 sessionStorage存储// paths需要持久存储的keystrategies: [{ storage: sessionStorage, paths: ["firstName", "lastName"] },{ storage: localStorage, paths: ["accessToken"] },],},}
);const cookiesStorage: any = {setItem(key:string, state:any): any {const myState = JSON.parse(state)return Cookies.set(key, myState[key], { expires: 3 })},getItem(key:string): string {return JSON.stringify({[key]: Cookies.get(key),})},removeItem(key) { },clear() { }}export const usePersistTestCokie = defineStore("persistTestCokie", () => {const username = ref("王者之巅")const counter = ref(100)const accessToken = ref("xxx")return { username, counter, accessToken }
}, {persist: {enabled: true,strategies: [{storage: cookiesStorage,key: 'username',paths: ['username']},{storage: cookiesStorage,key: 'counter',paths: ['counter']},{storage: cookiesStorage,key: 'accessToken',paths: ['accessToken']},],}
})
src/views/piniaTest.vue组建测试
<script setup lang="ts">
import { RouterLink, RouterView } from "vue-router";
import { usePersistTest,usePersistTestCokie } from "./stores/piniaPersistTest";const persistStore = usePersistTest();
const persistTestCokie = usePersistTestCokie()const changePersist = () => {persistStore.count++;persistStore.lastName = "测试name";persistStore.accessToken = "测试accessToken";persistStore.firstName = "测试第一name";
};
</script><template><button @click="changeCountHanlder">测试pinia</button>{{ counterStore.count }} 和 {{ counterStore.sum }}<br /><button @click="changePersist">持久存储</button>count:{{ persistStore.count }}<br>lastName:{{ persistStore.lastName }}<br>accessToken:{{ persistStore.accessToken }}<br>firstName:{{ persistStore.firstName }}<br>CokieSave:<button @click="persistTestCokie.accessToken='ddddfdf3434ffdsfsfs33'">存储cokie</button>username:{{ persistTestCokie.username }} counter:{{ persistTestCokie.counter }} accessToken:{{ persistTestCokie.accessToken }}
</template>