开发简易版Vuex(TypeScript)

在开发简易版Vuex之前,要了解一下Vuex的底层逻辑,点击去 了解详情

Vuex主要解决在项目规模大的情况下,单向数据流通太过局限,把所用的数据抽离成一个视图,在多个应用组件内随意调用。

知道Vuex所解决的痛点,我们围绕这个痛点来开发一个简易的Vuex

1、构建目录 及 整理思路

packages/* 包主要内容层
types/* 包内容标注类型
index.ts 导出包内容实例及注册方法

在这里插入图片描述
看到目录其实没有太多内容,因为是简易版的,我去除掉gettermutation以及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计算属性才能实现实时响应。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值