在开发简易版Vuex之前,要了解一下Vuex的底层逻辑,点击去 了解详情。
Vuex主要解决在项目规模大的情况下,单向数据流通太过局限,把所用的数据抽离成一个视图,在多个应用组件内随意调用。
知道Vuex所解决的痛点,我们围绕这个痛点来开发一个简易的Vuex
1、构建目录 及 整理思路
packages/* 包主要内容层
types/* 包内容标注类型
index.ts 导出包内容实例及注册方法
看到目录其实没有太多内容,因为是简易版的,我去除掉getter、mutation以及module
主要功能就是将变量集中在一个视图内,方便组件内调用。
2、Store主要功能
/packages/state.ts 创建state创建响应式数据
import { reactive } from 'vue';
import { InitState } from '../types/store';
// 提供一个 响应式数据
const state: InitState = reactive({
username: "leon"
})
export default state
/packages/action.ts 利用vue的computed 计算属性,实时抛出数据
import { computed } from 'vue';
import state from './state';
import { InitState } from '../types/store';
export default {
// 获取state 指定key的值
get: (K: keyof InitState): unknown => {
return computed(() => {
return state[K]
})
},
// 设置state 指定key的值
set: (K: keyof InitState, V: InitState[typeof K]): void => {
state[K] = V
},
}
types/store.d.ts 类型标注
export interface InitState {
username: string | null;
[prop: string | number]: number | Record<string, unknown> | Array<unknown | null> | string | null | undefined
}
注: 为什么要给state进行类型标注,一是为了规范数据来源,二是为了在取值及设置值的过程中是否正确。三能快速捕获数据类型相关的错误。
3、抛出包内容
/index.ts 挂载包
import type { App } from 'vue';
import actions from './packages/action';
import state from './packages/state';
const install = function (Vue : App): void {
if (!Vue) {
console.error("[store]未获取到Vue实例!");
return;
}
// 这里将实例 挂载在了Vue.config.globalProperties上
Vue.config.globalProperties.$store = {
...actions,
state,
}
}
// 抛出包内容
export default {
install,
...actions,
state,
}
4、将包内容挂载在Vue上
/src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from '@/store';
const app = createApp(App)
app.use(router)
// 是用use挂载包
app.use(store)
app.mount('#app')
export default app
5、使用 及 效果展示
<template>
<div class="about">
<h4>This is an about page</h4>
<h4>My name is {{ username }}</h4>
<h4 @click="test">{{ description }}</h4>
</div>
</template>
<script setup lang="ts">
import { getCurrentInstance, ComponentPublicInstance } from 'vue';
// getCurrentInstance.proxy 能获取到挂载在vue原型上的方法
const proxy: ComponentPublicInstance<any> = getCurrentInstance()?.proxy
const username = proxy.$store.get("username")
proxy.$store.set("desc", "一个store实例")
const description = proxy.$store.get("desc")
function test (): void {
proxy.$store.set("desc", "一个store实例 - 简易版")
}
</script>
点击后
数据是实时响应的,也可以通过proxy.$store.state.desc来获取,但是这样获取的变量不是实时响应的,需要用到computed计算属性才能实现实时响应。