JinZHouXiYiJi_DaPin2/examples/store/plugins/store.ts

117 lines
2.9 KiB
TypeScript
Raw Permalink Normal View History

2023-12-05 13:23:01 +08:00
import type {
PiniaPlugin,
PiniaPluginContext,
StateTree,
SubscriptionCallbackMutation
} from 'pinia'
import { Logger } from '@/utils/utils'
/**
* Storage
*/
export interface Storage {
getItem: (key: string) => any
setItem: (key: string, value: any) => void
removeItem: (key: string) => void
}
/**
*
*/
export interface Options {
/**
* `window.localStorage`
*/
storage?: Storage
/**
* key `pinia`
*/
key?: string
/**
* `false`
*/
logger?: boolean
activeStores?: Array<string>
}
/**
*
* @param mutationId
* @param mutation
* @param state
*/
function logGroup(
mutationId: string,
mutation: SubscriptionCallbackMutation<any>,
state: StateTree
) {
const group = Logger.groupCollapsed || Logger.group
try {
group(mutationId, new Date().toLocaleString())
Logger.log('mutation', mutation)
Logger.log('state', state)
Logger.groupEnd()
} catch (e) {
Logger.log('—— log end ——')
}
}
/**
* @params option
* @default options = { storage: window.localStorage, key: 'pinia', logger: false }
*/
export function StoragePlugin(options?: Options): PiniaPlugin {
const activeStores = options?.activeStores || []
const storage = options?.storage || (window && window.localStorage)
const key = options?.key || 'pinia'
const logger = options?.logger || false
// 获取state的值
const getState = (key: string, storage: Options['storage']) => {
const value = (storage as Storage).getItem(key)
try {
return typeof value === 'string'
? JSON.parse(value)
: typeof value === 'object'
? value
: undefined
} catch (err) {}
return undefined
}
// 设置state的值
const setState = (key: string, state: StateTree, storage: Options['storage']) => {
return (storage as Storage).setItem(key, JSON.stringify(state))
}
return (Context: PiniaPluginContext) => {
const store: PiniaPluginContext['store'] = Context.store
if (
(activeStores.length > 0 && activeStores.includes(store.$id)) ||
activeStores.length === 0
) {
const tempKey = `${key}-${store.$id}`
const data = getState(tempKey, storage)
data && store.$patch(data)
// $subscribe()一个 store的方法来观察 state 和它的变化,类似于 Vuex 的subscribe 方法
store.$subscribe(
(mutation: SubscriptionCallbackMutation<any>, state: StateTree) => {
// 记录日志
logger && logGroup(mutation.storeId, mutation, state)
const tempKey = `${key}-${mutation.storeId}`
setState(tempKey, state, storage)
},
{
immediate: true,
deep: true
}
)
}
// 初始化时获取数据如果有的话把原来的pinia的state替换掉
}
}