在开发基于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的方法
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可以对其进行修改.
<template> <div>{{num}}</div> <el-button @click="setNum">默认按钮</el-button> <div>接收父组件{{msg}}</div> <button @click="changeState">改变状态{{codes}}</button> </template> <script lang="ts"> import { computed, defineComponent, ref, onMounted, isRef } from "vue"; import { useStore } from "../store/store"; export default defineComponent({ name: "Parent", props: ["msg"], setup(context, prop) { const store = useStore(); let num = ref<number>(0); const setNum = () => { num.value++; }; onMounted(() => {}); const changeState = () => { store.action.updateCode("改变code"); }; const codes = computed(() => { return store.state.code; }); return { num, setNum, changeState, codes, }; }, watch: { msg(val, oldVal) { console.log(val, oldVal); }, }, }); </script> <style> </style>
这样我们就离开了Vuex并创建出了可是实时更新的数据中心.
持久化存储
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 }
发表评论
侧栏公告
寄语
譬如朝露博客是一个分享前端知识的网站,联系方式11523518。
热评文章
标签列表
热门文章
友情链接