In the development of Vue3 based projects, we found that we can easily manage data without relying on Vuex. We only need to use Composition Api to quickly establish a simple and understandable global data store.

Create the State

Reactive We create state, and the IState exposed is used to make it easy for other files to accept state objects

import { reactive } from 'vue'

export interface IState {
    code: string
    token: string
    user: any
}

export const State: IState = {
    code: '',
    token: '',
    user: {}
}

export function createState() {
    return reactive(State)
}
Copy the code

Create an Action

Let’s create an Action as our method for changing State

import { reactive } from 'vue' import { IState } from './state' function updateCode(state: IState) { return (code: string) => { state.code = code } } function updateToken(state: IState) { return (token: string) => { state.token = token } } function updateUser(state: IState) { return (user: Any) => {state.user = user}} /** * createAction * @param state */ export function createAction(state: IState) { return { updateToken: updateToken(state), updateCode: updateCode(state), updateUser: updateUser(state) } }Copy the code

Code access to State can also be achieved through exposed IState.

Create the Store

Once the State and Action are created, we integrate them through the Store.

import { reactive, readonly } from 'vue'
import { createAction } from './action'
import { createState } from './state'

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

export const useStore = () => {
    const store = {
        state: readonly(state),
        action: readonly(action)
    }

    return store
}
Copy the code

This allows us to access and modify State in the project by calling useStore. Since the State returned by useStore is generated by ReadOnly, we make sure that only Action can modify it.

// Call state const store = useStore() store.state.code // Call action const Store = useStore() store.action.updatecode (123)Copy the code

So we left Vuex and created a data center that was updated in real time.

Persistent storage

The data in many stores still need to be stored persistently to ensure that the data is still available after the page is refreshed. We mainly implement the persistent storage based on Watch

import { watch, toRaw } from 'vue' export function createPersistStorage<T>(state: any, key = 'default'): T { const STORAGE_KEY = '--APP-STORAGE--' // init value 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) localStorage.setItem(STORAGE_KEY, stateStr) } function getItem(key? : string) { const stateStr = localStorage.getItem(STORAGE_KEY) || '{}' const stateRow = JSON.parse(stateStr) || {} return key ? stateRow[key] || {} : stateRow } watch(state, () => { const stateRow = toRaw(state) setItem(stateRow) }) return readonly(state) }Copy the code

Through watch and toRaw, we realized the interaction between state and localstorage.

Simply change the readOnly to createPersistStorage

export const useStore = () => {
    const store = {
        state: createPersistStorage<IState>(state),
        action: readonly(action)
    }

    return store
}
Copy the code

This enables persistent support for Store data.