强大的Vuex输入模块

撰写本文的动机是另一篇有关Vue以及相应的Vuex打字的文章 。 令我惊讶的是,我在那里没有发现任何模块,我认为这是Vuex最好的模块。 可是,在Habr,甚至在Runet中搜索(实际上,在英语源中很难立即找到任何参考文献)都没有产生任何结果。 这篇文章不是有关使用和配置的详细分析和多页手册,而是一种与您共享的方式,亲爱的Vue-ninja,它是一款功能出色的工具。

vuex-smart-module


谁都没有时间: Github

您可能已经猜到了,该模块的主要目的是对Vuex存储的类型进行全格式介绍。 在内部和直接在组件本身中。 该模块由Vuexvue-class-component库的主要贡献者( @ktsn )编写。


要承认,我在Typescript中的道路才刚刚开始,包括 以及诸如装饰器之类的东西,因此我无法将此库与其他类似物进行比较。 我尝试配置和使用其他工具(例如vuex-module-decorators )使我遇到了各种各样的问题,最终导致我以某种方式无法意识到自己需要的东西(或者我只是不知道如何烹饪它们,正如他们所说的那样)。 我对vuex-smart-module很幸运-当我将项目(和存储库)转换为Typescript的那一刻,该库就出现了。 现在一切正常,代码令人赏心悦目。

例子


我认为该库具有良好的文档,其中涵盖了您将遇到的所有可能情况(如果没有,那么在测试中,您会发现其他所有琐碎的事情)。 但是,为了至少以某种方式用代码稀释文章,我将给出连接和使用的基本示例,几个“生活”示例,以及它与装饰器一起工作的方式(有细微差别)。

模块创建


使用类创建模块。 这似乎使某些人感到异常恐惧,但请相信我,您很快就习惯了。

存储/ root.ts

//    import { Getters, Mutations, Actions, Module } from 'vuex-smart-module' //  class RootState { count = 1 } //  //      RootState class RootGetters extends Getters<RootState> { get double() { //      `state` return this.state.count * 2 } get triple() { //       `getters` return this.getters.double + this.state.count } } //  //     ,     RootState class RootMutations extends Mutations<RootState> { increment(payload: number) { //       `state` this.state.count += payload } } //  //     //    ,       ,      class RootActions extends Actions< RootState, RootGetters, RootMutations, RootActions > { incrementAsync(payload: { amount: number; interval: number }) { //      `state`, `getters`, `commit`  `dispatch` return new Promise(resolve => { setTimeout(() => { this.commit('increment', payload.amount) }, payload.interval) }) } } //   export default new Module({ state: RootState, getters: RootGetters, mutations: RootMutations, actions: RootActions }) 

连接方式


/store/index.ts

 import Vue from 'vue' import * as Vuex from 'vuex' import { createStore } from 'vuex-smart-module' import RootStore from './root' Vue.use(Vuex) export const store = createStore( RootStore, { strict: process.env.NODE_ENV !== 'production' } ) 

模组


连接模块与常规Vuex中的连接方式相似。 需要在RootStore的modules属性中指定它们:

 import FooStore from './modules/foo' /* … */ export default new Module({ state: RootState, getters: RootGetters, mutations: RootMutations, actions: RootActions, modules: { FooStore } }) 

在组件内部使用


您可以通过全局属性this。$ Store和映射使用stor,这在许多方面与Vuex中的存储相似:

 import Vue from 'vue' //    (      ) // import FooStore from '@/store/modules/foo' import RootStore from '@/store/root' export default Vue.extend({ computed: RootStore.mapGetters(['double']), methods: RootStore.mapActions({ incAsync: 'incrementAsync' }), created() { console.log(this.double) this.incAsync(undefined) } }) 


打字


键入提交和分发的示例:
 import { categories } from '@/api' export type Category { attributes: { hasPrice: boolean; icon: string lvl: number name: string slug: string }; id: number } export interface IParams { city_id: number } class AppState { categories: Category[] = [] } /* ... */ class AppMutations extends Mutations<AppState> { setCategories(categories: Category[]) { this.state.categories = categories } } class AppActions extends Actions< AppState, AppGetters, AppMutations, AppActions > { async getCategories({params}: {params: IParams}): Promise<Category[]> { return categories.get({params}).then( ({ data }: { data: Category[] }) => { this.commit("setCategories", data) return data } ) } } 


招待会


使用装饰器( vue-property-decorator )连接


 import { Vue, Component } from "vue-property-decorator" //    (      ) // import FooStore from '@/store/modules/foo' import RootStore from "@/store/root" //  ,   ,      Typescript,     : const Mappers = Vue.extend({ computed: { ...RootStore.mapGetters(["double"]) }, methods: { ...RootStore.mapActions({ incAsync: 'incrementAsync' }) } }); @Component export default class MyApp extends Mappers { created() { console.log(this.double) this.incAsync(undefined) } } 

在模块内部使用模块


/store/module/bar.ts

 import { Store } from 'vuex' import { Getters, Actions, Module, Context } from 'vuex-smart-module' //    import FooStore from './foo' /* … */ class BarGetters extends Getters { //   foo!: Context<typeof FooStore>; //     $init(store: Store<any>): void { //     this.foo = FooStore.context(store) } get excited(): string { return this.foo.state.value + '!' // -> hello! } } /* … */ 

保管箱重设


有时可能需要将存储重置为默认值,这非常简单:

 class FooState { /* ... */ } class FooMutations extends Mutations<FooState> { reset () { const s = new FooState() Object.keys(s).forEach(key => { this.state[key] = s[key] }) } } 

决赛


我希望您对此感兴趣,或者至少您对这个库有所了解。 谁知道,也许从下一个项目开始(或者可能重构当前的项目?),像我一样,您将开始使用vuex-smart-module(或通常的Typescript)吗? 就个人而言,我过渡到Typescript的过程非常痛苦(在1.5-2年中,我尝试至少切换3-4次,但是每次遇到一些问题时,都会产生误解。我常常被Typescript开发需要的感觉困扰时间比以前多了2-3倍,因为现在您不能只是“快速勾勒出草图”。但是一旦踏上“静态键入的亮面”,我就感受到了类型的力量以及它们最终如何被允许使用加快开发过程,这同样重要,调试代码(也许在相同的2- 3次)​​,以及方便其进一步的支持。

PS不要忘记在此模块上加一个星号。 :)

感激之情
最后,我要感谢我心爱的妻子的耐心,感谢猫咪在桌子旁隆隆的隆隆声,感谢邻居的沉默以及您的关注!

Source: https://habr.com/ru/post/zh-CN459050/


All Articles