使用 NuxtJS 和 vuex-module-decorators 的动态 vuex 存储模块

Posted

技术标签:

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

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

我尝试关注guide from the official nuxt website 和vuex-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 s-s-r 的唯一方法,那就没问题了。

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

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

【问题讨论】:

你最终找到答案了吗? @MikeOttink 不。正如我的问题中提到的,我放弃并使用了 vuex-class-component。 也放弃了使用vuex-class-component。像魅力一样工作,并且只有一小部分样板。 【参考方案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
    

【讨论】:

以上是关于使用 NuxtJS 和 vuex-module-decorators 的动态 vuex 存储模块的主要内容,如果未能解决你的问题,请参考以下文章

NuxtJS 身份验证代理

NuxtJS 状态更改和 firebase 身份验证

NuxtJS / Vuex | nuxtServerInit 和 fetchData 操作未填充用户状态

使用@nuxtjs/tailwindcss 清除了 SCSS 样式

使用本地策略实现 nuxtjs/auth 的问题

使用 AVA 和 TypeScript 测试 Nuxtjs 应用程序