有了hooks,手写状态轮子,不需要vuex、pinia

2022-07-12  本文已影响0人  HomWang

1.默认state结构

import { reactive } from 'vue'
export interface IState {
  locale: string
}
export const State: IState = {
  locale: 'zh-CN'
}

2.创建action

import { IState, State as storeState } from "./state"
function updateLocale(state: IState) {
  return (locale: string) => {
    state.locale = locale
  }
}

export function createAction(state: IState) {
  return {
    updateLocale: updateLocale(state),
  }
}

3.写hook
import { reactive, readonly } from 'vue'
import { createAction } from '../stores/action'
import { createPersistStorage } from '../stores/persistStorage'
import { createState, IState } from '../stores/state'

const state = createState()
const action = createAction(state)

export const useStore = () => {
const store = {
// 这里需要兼容服务端还是客户端
state: process.client ? createPersistStorage<IState>(state) : readonly(state),
action: readonly(action)
}
return store
}

4.存储createPersistStorage
import { watch, toRaw } from 'vue'
import * as Cookies from 'js-cookie';

export function createPersistStorage<T>(state: any, key = 'default'): T {
const STORAGE_KEY = '需要存储的key'

Object.entries(getItem(key)).forEach(([key, value]) => {
state[key] = value
})

function setItem(state: any) {
const stateRow = getItem()
stateRow[key] = state
const stateStr = JSON.stringify(stateRow)
if(process.client){
localStorage.setItem(STORAGE_KEY, stateStr)
}else{
Cookies.set(STORAGE_KEY, stateStr, { expires: 365, secure: false })
}
}

function getItem(key?: string) {
let stateStr: any
if(process.client){
stateStr = localStorage.getItem(STORAGE_KEY) || '{}'
}else{
stateStr = Cookies.get(STORAGE_KEY) || '{}'
}
const stateRow = JSON.parse(stateStr) || {}
return key ? stateRow[key] || {} : stateRow
}

watch(state, () => {
const stateRow = toRaw(state)
setItem(stateRow)
})

return readonly(state)
}

使用:
const store = useStore()
store.action.updateLocale('zh-CN')

这样就能够实现状态管理器,所以不需要第三方插件,当然如果你想用现成的第三方包那也没事儿,毕竟自己手写的感觉会很酷

上一篇下一篇

猜你喜欢

热点阅读