taro + vue3 + pinia 持久化存储到 storage

844 阅读1分钟
// src/plugins/piniaPersistedState
import { getStorageSync, setStorageSync } from '@tarojs/taro';

const hydrateStore = (store, { key }) => {
	try {
		const value = getStorageSync(key);
		if (value) store.$patch(value);
	} catch (error) {
		console.error('--> piniaPersistedState.hydrateStore', error);
	}
};

const persistState = (state, { key, paths }) => {
	try {
		if (!Array.isArray(paths)) return;
		const toStore = paths.reduce((total, cur) => (state[cur] ? { ...total, [cur]: state[cur] } : total), {});
		setStorageSync(key, toStore);
	} catch (error) {
		console.error('--> piniaPersistedState.persistState', error);
	}
};

export function createPersistedState() {
	return context => {
		const { options, store } = context;
		const { id, persist } = options;

		if (!persist) return;
		const currentId = `store_${id}`;
		const { paths } = persist;

		hydrateStore(store, { key: currentId });

		store.$subscribe(
			(_mutation, state) => {
				persistState(state, { key: currentId, paths });
			},
			{
				detached: true,
			}
		);
	};
}

// scr/app.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { createPersistedState } from '@/plugins/piniaPersistedState';

const App = createApp();
const pinia = createPinia();
pinia.use(createPersistedState());
App.use(pinia);

export default App;

使用

import { defineStore } from 'pinia';

export const useAuthStore = defineStore({
	id: 'auth',
	state: () => ({
		authInfo: {},
		userInfo: {},
		token: '',
	}),
	persist: {
		paths: ['token', 'authInfo'], // paths 为需要写到 storage 里的 key
	},
});

// 业务页面
const authStore = useAuthStore();
authStore.$patch({ token: 'xxx' }) // 会写到 storage