【问题标题】:Dynamic vuex store modules with NuxtJS and vuex-module-decorators使用 NuxtJS 和 vuex-module-decorators 的动态 vuex 存储模块
【发布时间】:2020-06-05 23:06:27
【问题描述】:

我很难让我的 vuex 模块与 NuxtJS SSR、TypeScript 和 vuex-module-decorators 一起使用。

我尝试关注guide from the official nuxt websitevuex-module-decorators,但没有任何效果...

这是我的代码:

// store/CommonModule.ts
import { Module, VuexModule, Mutation } from 'vuex-module-decorators'

@Module({
  name: 'CommonModule',
  namespaced: true,
  stateFactory: true,
})
export default class CommonModule extends VuexModule {
  message: string = 'hi'

  @Mutation
  public SET_MESSAGE(val: string) {
    this.message = val
  }
}
// store/index.ts
import Vuex from 'vuex'
import CommonModule from '~/store/CommonModule'

export function createStore() {
  return new Vuex.Store({
    modules: {
      CommonModule,
    },
  })
}
// components/Home.vue
import { Component, Vue } from 'vue-property-decorator';
import { getModule } from 'vuex-module-decorators';
import CommonModule from '~/store/CommonModule'

@Component
export default class Home extends Vue {
    get message(): string {
        const commonModule = getModule(CommonModule, this.$store)
        return commonModule.message // throws an error: Cannot read property 'message' of undefined
    }
}

每当我尝试访问模块中的任何内容时,这些都是未定义的...

我知道这种方法是“静态模块”。我的目标是使用动态模块,但如果静态模块是使用 NuxtJS SSR 的唯一方法,那就没问题了。

任何帮助将不胜感激。谢谢:)

编辑
我放弃了,用vuex-class-component

【问题讨论】:

  • 你最终找到答案了吗?
  • @MikeOttink 不。正如我的问题中提到的,我放弃并使用了 vuex-class-component。
  • 也放弃了使用vuex-class-component。像魅力一样工作,并且只有一小部分样板。

标签: typescript vue.js vuex nuxt.js


【解决方案1】:

如果您试图让您的商店模块动态注册,那么您在 index.ts 文件中所做的操作是不正确的。

在 store/index.ts 中定义一个空的 store

import Vuex from 'vuex'

export const store = new Vuex.Store<any>({});

现在在您的商店模块中:

// store/CommonModule.ts
import { Module, VuexModule, Mutation } from 'vuex-module-decorators'

// import the empty store
import store from '.'

@Module({
  name: 'CommonModule',
  namespaced: true,
  stateFactory: true,

  // add this
  dyamic:true,
  store

})
export default class CommonModule extends VuexModule {
  message: string = 'hi'

  @Mutation
  public SET_MESSAGE(val: string) {
    this.message = val
  }
}

【讨论】:

    【解决方案2】:

    正在与类似问题作斗争,并使其与此页面中的代码一起工作:https://qiita.com/yoshinbo/items/70f109db7c3de4b4a99f

    • 在模块定义中使用存储
    • 从模块文件中导出 getModule 的结果
    • 默认从 ~/store/index.ts 导出 createStore

    【讨论】:

    • 谢谢,这有帮助!
    • 太棒了。 store.state.moduleName.stateName 也可以。并且可以在中间件中使用。
    【解决方案3】:

    嗯,你需要在 created() 生命周期钩子中调用 Message() 函数。

    目前根据您的代码,只要组件初始化,脚本就会开始执行,但到那时尚未设置存储,因为在生命周期挂钩中调用它会更有意义。

    public created() {
      get message(): string {
        const commonModule = getModule(CommonModule, this.$store)
        return commonModule.message;
      }
    }
    
    

    希望这会有所帮助!

    【讨论】:

    • 其实我的消息函数是一个getter,在函数内部声明getter是无效的(抛出错误)。
    • 我放弃了,转到了 vuex-module-class。这个正在为 nuxt 工作。
    【解决方案4】:

    对于仍想使用vuex-module-decorator的任何人:

    从 Atlasmaybe 的问题示例中,它缺少一个 store-accessor.ts 文件:check the docs

    我们必须对现有文件进行一些调整,我们将在这个新文件中使用getModule 函数:

    1 - 首先在我们的自定义模块中:

    // store/CommonModule.ts
    import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
    
    @Module({
      // change the name to lower case
      name: 'commonmodule',
      namespaced: true,
      stateFactory: true,
    })
    // no need to name the class:
    export default class extends VuexModule {
      message: string = 'hi'
    
      @Mutation
      public SET_MESSAGE(val: string) {
        this.message = val
      }
    }
    

    2 - 然后在utils 文件夹中创建一个store-accessor.ts 文件:

    // utils/store-accessor.ts
    import { Store } from 'vuex'
    import { getModule } from 'vuex-module-decorators'
    import commonmodule from '~/store/CommonModule'
    
    // this is the name we'll use to import the module
    let commonModuleStore: commonmodule
    
    function initialiseStores(store: Store<any>): void {
      commonModuleStore = getModule(commonmodule, store)
    }
    
    export { initialiseStores, commonModuleStore }
    

    3 - 现在在您的商店index.ts:

    // store/index.ts
    import { Store } from 'vuex';
    import { initialiseStores } from '~/utils/store-accessor';
    
    const initializer = (store: Store<any>) => initialiseStores(store);
    
    export const plugins = [initializer];
    
    export * from '~/utils/store-accessor';
    

    4 - 最后在我们的组件中,我们可以导入自定义存储并像这样使用它:

    // components/Home.vue
    import { Component, Vue } from 'vue-property-decorator';
    
    // import goes from:
    // import CommonModule from '~/store/CommonModule';
    // to:
    import { commonModuleStore } from '~/store';
    
    @Component
    export default class Home extends Vue {
        get message(): string {
            // usage:
            commonModuleStore.SET_MESSAGE('hello world');
            console.log(commonModuleStore.message); // hello world
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-23
      • 2019-09-14
      • 2020-11-05
      • 2020-03-07
      • 2021-01-06
      • 2021-11-14
      • 2021-07-15
      • 2019-09-07
      • 2021-01-27
      相关资源
      最近更新 更多