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

查看 16|回复 0
作者:zcf0508   
一转眼已经 2023 年了,vue2 即将在年底寿终正寝。但是现在谁手里还没有几个 vue2 的项目呢。在 vue3 全面拥抱 ts 的时刻,我希望我手里的这个 vue2 项目也能够更好的类型提示,有更好的开发体验。
在最近改造项目的过程中,愈发觉得 vuex 是 vue2 全面拥抱 ts 的一大阻碍。vuex 在设计之初就没有考虑类型,导致无论是定义 Module 或者在组件中使用 mapX 函数,都会导致页面出现大量的类型错误。
💐经过几天的努力,我初步完成了更好用的带类型的 vuex。项目详情请跳转 z-vuex-typed。
设计初衷
[ol]
  • 提供完善的类型提示
    [/ol]
    完善的类型提示包括在定义 Module 和 Store 时,能够对 mutations 、actions 、getters 的函数参数有足够的类型提示。还包括在使用 mapX 函数时,能够提供参数的可选值,并且在组件内使用 mapX 函数时,组件也能正确知道引入的数据和方法的类型。
    [ol]
  • 尽量简单的迁移过程
    [/ol]
    我不希望引入这个项目会给原项目带来过多的改造,这就是为什么不选择使用 pinia 重构项目的原因。这个项目只引入两个新的方法 defineModule 和 defineStore 作为包装,以便正确获得类型推断。
    [ol]
  • 不改变 vuex 的行为
    [/ol]
    这个项目只覆盖默认 vuex 的类型,即使类型出错,也完全不会导致 vuex 的行为异常,这使得给 vuex 增加类型不会造成任何的副作用。
    安装
    为了覆盖 vuex 的类型,需要在安装 z-vuex-typed 的同时卸载 vuex ,避免类型冲突
    npm uninstall vuex
    npm install z-vuex-typed
    使用方法
    [ol]
  • 使用 defineModule 定义 Modules
    [/ol]
    import { defineModule } from 'z-vuex-typed'
    const userModule = defineModule({
        // ... 直接迁移之前已有的定义,会有完善的类型定义
    })
    export default userModule
    [ol]
  • 使用 defineStore 定义 Store
    [/ol]
    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,
    }
    [ol]
  • 修改 vue 中 $store 的定义
    [/ol]
    由于前面我们已经卸载了 vuex ,所以我们需要手动生命 $store 的类型。
    // src/shims-vuex.d.ts
    import Vue, { ComponentOptions } from 'vue'
    import store from '@/store'
    declare module 'vue/types/options' {
      interface ComponentOptions {
        store?: typeof store
      }
    }
    declare module 'vue/types/vue' {
      interface Vue {
        $store: typeof store
      }
    }
    [ol]
  • 修改组件中 mapX 方法的引入方式
    [/ol]
    尾巴
    已经 2023 年了,大家在创建新项目时相必一定不会再选择 vuex 了。但是如果不得不维护旧项目,又想要获得更好的开发体验,大家可以尝试一下这个项目,如果大家对这个项目有兴趣,欢迎根据前面的教程对项目进行改造。
    如果你发现任何 bug ,欢迎给我提 issue 。
  • 您需要登录后才可以回帖 登录 | 立即注册

    返回顶部