已经 2023 年了,给 vuex 补充类型还值得吗

272 天前
 zcf0508

一转眼已经 2023 年了,vue2 即将在年底寿终正寝。但是现在谁手里还没有几个 vue2 的项目呢。在 vue3 全面拥抱 ts 的时刻,我希望我手里的这个 vue2 项目也能够更好的类型提示,有更好的开发体验。

在最近改造项目的过程中,愈发觉得 vuex 是 vue2 全面拥抱 ts 的一大阻碍。vuex 在设计之初就没有考虑类型,导致无论是定义 Module 或者在组件中使用 mapX 函数,都会导致页面出现大量的类型错误。

💐经过几天的努力,我初步完成了更好用的带类型的 vuex。项目详情请跳转 z-vuex-typed

设计初衷

  1. 提供完善的类型提示

完善的类型提示包括在定义 Module 和 Store 时,能够对 mutations 、actions 、getters 的函数参数有足够的类型提示。还包括在使用 mapX 函数时,能够提供参数的可选值,并且在组件内使用 mapX 函数时,组件也能正确知道引入的数据和方法的类型。

  1. 尽量简单的迁移过程

我不希望引入这个项目会给原项目带来过多的改造,这就是为什么不选择使用 pinia 重构项目的原因。这个项目只引入两个新的方法 defineModuledefineStore 作为包装,以便正确获得类型推断。

  1. 不改变 vuex 的行为

这个项目只覆盖默认 vuex 的类型,即使类型出错,也完全不会导致 vuex 的行为异常,这使得给 vuex 增加类型不会造成任何的副作用。

安装

为了覆盖 vuex 的类型,需要在安装 z-vuex-typed 的同时卸载 vuex ,避免类型冲突

npm uninstall vuex
npm install z-vuex-typed

使用方法

  1. 使用 defineModule 定义 Modules
import { defineModule } from 'z-vuex-typed'

const userModule = defineModule({
    // ... 直接迁移之前已有的定义,会有完善的类型定义
})

export default userModule
  1. 使用 defineStore 定义 Store
import { defineStore } from 'z-vuex-typed'
import userModule fomr './modules/user'

const { 
    store ,
    mapMutations,
    mapActions,
    mapGetters,
} = defineStore({
    modules: {
        user: userModule
    },
    // ... 同样直接迁移之前已有的定义
    getters: {
        // ... 需要注意的是,为了让全局的 getters 拥有完备的类型定义,需要直接在这里写 getters
        //  而不能在外部定义后再引入
    }
})

// 正常导出 store
export default store

// 导出带类型的 maoX 函数
export {
    mapMutations,
    mapActions,
    mapGetters,
}

  1. 修改 vue 中 $store 的定义

由于前面我们已经卸载了 vuex ,所以我们需要手动生命 $store 的类型。

// src/shims-vuex.d.ts
import Vue, { ComponentOptions } from 'vue'
import store from '@/store'

declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    store?: typeof store
  }
}

declare module 'vue/types/vue' {
  interface Vue {
    $store: typeof store
  }
}

  1. 修改组件中 mapX 方法的引入方式
<script>
// improt { mapMutations, mapActions, mapGetters } from 'vuex'
improt { mapMutations, mapActions, mapGetters } from '@/store'
</script>

尾巴

已经 2023 年了,大家在创建新项目时相必一定不会再选择 vuex 了。但是如果不得不维护旧项目,又想要获得更好的开发体验,大家可以尝试一下这个项目,如果大家对这个项目有兴趣,欢迎根据前面的教程对项目进行改造。

如果你发现任何 bug ,欢迎给我提 issue 。

2105 次点击
所在节点    分享创造
3 条回复
amlee
272 天前
图啥呢,旧项目直接叠屎不得了
justBugCoder
271 天前
vue2 钉子户在此
zcf0508
271 天前
@justBugCoder 升级到 2.7 ,打开 checkjs ,打开 volar 自动补充 defineComponent ,用我的这个项目更换 vuex ,你会获得更完美的开发体验

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/966672

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX