vue.js - Vuex:具有动态命名空间的 createNamespacedHelpers

标签 vue.js vuejs2 vue-component vuex vuex-modules

在我看到的几乎所有关于 vuex 模块注册的指南、教程、帖子等中,如果模块是由组件注册的,则 createNamespacedHelpers 会在 export 之前导入和定义default 组件语句,例如:

import {createNamespacedHelpers} from 'vuex'
const {mapState} = createNamespacedHelpers('mymod')

import module from '@/store/modules/mymod'

export default {
  beforeCreated() {
    this.$store.registerModule('mymod', module)
  }
}

这按预期工作,但如果我们希望模块具有唯一或用户定义的命名空间怎么办?

import {createNamespacedHelpers} from 'vuex'
import module from '@/store/modules/mymod'

export default {
  props: { namespace: 'mymod' },
  beforeCreated() {
    const ns = this.$options.propData.namespace
    this.$store.registerModule(ns, module)
    const {mapState} = createNamespacedHelpers(ns)
    this.$options.computed = {
      ...mapState(['testVar'])
    }
  }
}

我以为这行得通,但行不通。

为什么需要这样的东西? 因为

export default {
  ...
  computed: {
    ...mapState(this.namespace, ['testVar']), 
    ...
  },
  ...
}

不工作

最佳答案

这种通过使用 beforeCreate 来访问你想要的变量的工作方式应该可以工作,我是根据传递到你的组件实例中的 props 做的:

import { createNamespacedHelpers } from "vuex";
import module from '@/store/modules/mymod';

export default {
  name: "someComponent",
  props: ['namespace'],
  beforeCreate() { 
    let namespace = this.$options.propsData.namespace;
    const { mapActions, mapState } = createNamespacedHelpers(namespace);

    // register your module first
    this.$store.registerModule(namespace, module);

    // now that createNamespacedHelpers can use props we can now use neater mapping
    this.$options.computed = {
      ...mapState({
        name: state => state.name,
        description: state => state.description
      }),

      // because we use spread operator above we can still add component specifics
      aFunctionComputed(){ return this.name + "functions";},
      anArrowComputed: () => `${this.name}arrows`,
    };

    // set up your method bindings via the $options variable
    this.$options.methods = {
      ...mapActions(["initialiseModuleData"])
    };
  },

  created() {
    // call your actions passing your payloads in the first param if you need
    this.initialiseModuleData({ id: 123, name: "Tom" });
  }
}

我个人在我正在导入的模块中使用了一个辅助函数来获取命名空间,所以如果我有我的模块存储项目并使用路由器将 123 的 projectId 传递到我的组件/页面和/或 Prop 看起来像这样:

import projectModule from '@/store/project.module';

export default{
  props['projectId'], // eg. 123
  ...
  beforeCreate() {
    // dynamic namespace built using whatever module you want:
   let namespace = projectModule.buildNamespace(this.$options.propsData.projectId); // 'project:123'

   // ... everything else as above
  }
}

希望你觉得这很有用。

关于vue.js - Vuex:具有动态命名空间的 createNamespacedHelpers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54593910/

相关文章:

javascript - 主应用程序组件无法找到将 Vue 组件移动到单独的文件中

javascript - 如何在vue.js循环中实现运行平衡?

javascript - 如何在 VueJS Material 上隐藏/显示 <md-progress-bar>

javascript - 限制用户对 Firebase 节点的读/写访问权限不起作用

javascript - 使用 Vue.js 和 Firebase 进行验证

javascript - 如何在 Vue 计算属性中重用带参数的函数?

java - 当数据更新时,VueJS DOM 不更新

vue.js - Vue v-if 和移除 span

javascript - Vuejs路由刷新时重定向

vue.js - vuejs2 - 如何为单个文件组件层次结构创建事件总线