Vue3,我决定不再使用Vuex
在开发基于Vue3的项目中发现我们可以不再依赖Vuex也能很方便的来管理数据,只需要通过Composition Api
可以快捷的建立简单易懂的全局数据存储.
创建State
通过reactive
我们来创建state,暴露的IState
是用来方便其他文件来接受State
对象
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)
}
创建Action
我们来创建Action
来作为我们修改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
}
}
/**
* 创建Action
* @param state
*/
export function createAction(state: IState) {
return {
updateToken: updateToken(state),
updateCode: updateCode(state),
updateUser: updateUser(state)
}
}
通过暴露的IState
我们也可以实现对State的代码访问.
创建Store
创建好State
和Action
后我们将它们通过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
}
这样我们就可以在项目中通过调用useStore
访问和修改State
,因为通过useStore
返回的State
是通过readonly
生成的,所以就确认只有Action
可以对其进行修改.
// 访问state
const store = useStore()
store.state.code
// 调用action
const store = useStore()
store.action.updateCode(123)
这样我们就离开了Vuex并创建出了可是实时更新的数据中心.
持久化存储
很多Store中的数据还是需要实现持久化存储,来保证页面刷新后数据依然可用,我们主要基于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)
}
通过watch
和toRaw
我们就实现了state
和localstorage
的交互.
只需要将readonly
更换成createPersistStorage
即可
export const useStore = () => {
const store = {
state: createPersistStorage<IState>(state),
action: readonly(action)
}
return store
}
这样也就实现了对Store数据的持久化支持.
作者:程序员紫菜苔
链接:https://juejin.cn/post/6898504898380464142