映射到命名空间模块时,将prop作为模块名称传递

时间:2017-03-03 17:27:49

标签: javascript vue.js vuejs2 vue-component vuex

我正在尝试通过props将商店模块命名空间传递给组件。当我尝试使用道具映射到getter时,会抛出此错误,

未捕获的TypeError:无法将undefined或null转换为对象

如果我将名称作为字符串传递,则可以正常工作。

此作品

<script>
export default {

  props: ['store'],

  computed: {
    ...mapGetters('someString', [
      'filters'
    ])
  }
}
</script>

这不起作用

this.store被定义为 this.store typeof是一个String

<script>
  export default {

    props: ['store'],

    computed: {
      ...mapGetters(this.store, [
        'filters'
      ])
    }
  }
</script>

4 个答案:

答案 0 :(得分:0)

我也解决了几个小时的问题。然后我终于想到了一个主意。

  • 在子vue组件中添加attachStore函数。函数名不重要。除了vue保留字外,任何名称都可以。

    export default {
      :
      attachStore (namespace) {
        Object.assign(this.computed, mapGetters(namespace, ['filters']))
      }
    }
    
  • 导入此vue组件后,请使用命名空间参数调用attachStore。然后在父组件属性上使用它。

    import Child from './path/to/child'
    
    Child.attachStore('someStoresName')
    
    export default {
      name: 'parent',
      components: { Child }
      :
    }
    

答案 1 :(得分:0)

请注意,Vue的Github页面上也对此进行了讨论:https://github.com/vuejs/vuex/issues/863

直到Vue正式支持它,我替换了类似的东西

4

使用

...mapState({
  foo: state => state.foo
})

使用道具将foo () { return this.$store.state[this.namespace + '/foo'] || 0 } 传递到我的子组件的位置:

namespace

答案 2 :(得分:0)

我使用这种样式利用beforeCreate访问所需的变量,我使用了传递到组件实例中的道具:

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" });
  }
}

我个人在导入的模块中使用辅助函数来获取名称空间,因此,如果我有我的模块来存储项目,并使用路由器和/或道具将projectId 123传递给我的组件/页面,它将看起来像这样:

import { createNamespacedHelpers } from "vuex";
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 with no need to drop namespaces everywhere
   this.$options.computed = {
      ...mapState({
        name: state => state.name,
        description: state => state.description
      })
   }
  }
}

希望您觉得这有用。

答案 3 :(得分:-1)

在Vue / Vuex的初始化过程中,您遇到的错误正在抛出,this.store无法转换,因为它尚不存在。我还没有使用命名空间,这是未经测试的,所以我不知道它是否可行,但你可以通过这样的中间人来解决这个问题:

<script>
  export default {

    props: ['store'],

    data {
        namespace: (this.store !== undefined) ? this.store : 'null',
    },

    computed: {
      ...mapGetters(this.namespace, [
        'filters'
      ])
    }
  }
</script>

如果this.store未定义,那么三元表达式将返回一个字符串,如果它未定义,那么它将返回this.store中的值。

相关问题