美文网首页
有了hooks,手写状态轮子,不需要vuex、pinia

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

作者: HomWang | 来源:发表于2022-07-12 10:36 被阅读0次

    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')

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

    相关文章

      网友评论

          本文标题:有了hooks,手写状态轮子,不需要vuex、pinia

          本文链接:https://www.haomeiwen.com/subject/upoobrtx.html