使用NuxtJS和vuex-module-decorators实现动态的vuex store模块

7

我在NuxtJS SSR、TypeScript和vuex-module-decorators中使用vuex模块遇到了麻烦。

我尝试按照官方nuxt网站的指南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 SSR正常工作的唯一方法,那就没问题了。
非常感谢任何帮助。谢谢 :)
编辑 我放弃了并使用了vuex-class-component

你最终找到了这个问题的答案吗? - anonymous-dev
@MikeOttink 不是的。正如我在问题中提到的那样,我放弃了并使用了vuex-class-component。 - Atlasmaybe
也放弃了,使用了vuex-class-component。它运行良好且具有少量的样板代码。 - Jason Simpson
4个回答

5

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

请在store/index.ts中定义一个空存储。

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
  }
}


3

谢谢,这很有帮助! - Grey2k
store.state.moduleName.stateName同样可行,可以在中间件中使用。 - Dorin

1

好的,您需要在created()生命周期钩子内调用Message()函数。

根据您的代码,脚本当前在组件初始化时开始执行,但此时存储尚未设置,因此在生命周期钩子内调用它会更有意义。

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


希望这可以帮到你!

实际上,我的消息函数是一个getter,声明一个getter函数不是有效的(会抛出错误)。 - Atlasmaybe
1
我放弃了,转而使用vuex-module-class。这个可以在nuxt中工作。 - Atlasmaybe

0

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

从Atlasmaybe的问题示例中,缺少一个store-accessor.ts文件:查看文档

我们需要对现有文件进行一些调整,并在这个新文件中使用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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接