如何构建多用途Vue组件以从不同的Vuex路径加载数据?

时间:2018-03-15 18:13:29

标签: vue.js vuex

我想创建一个组件,我可以多次实例化指向(从其加载数据)不同的vuex命名空间。该组件将从Vuex获取大部分数据。所以说我有一个Person组件,我可以根据进入vuex的不同路径实例化Person组件的许多副本。

我弄清楚如何做到这一点的最好方法是将vuex路径作为道具传递,但后来我不知道如何使用mapGetters和朋友,因为它们在.vue时需要命名空间文件被实例化。

我很欣赏有关构建此事的最佳“Vue方式”的见解。这是我目前最接近的方法。

Person.vue:

<template>
    <div>person {{name}} is {{age}} years old</div>
</template>

<script>
  export default {
    props: ['vuexNamespaceToLoadFrom'],

    // FIXME: how do I do a mapGetters with a dynamic namespace that's 
    // set through props???

    // I can't do the following since props aren't in scope yet :-(
    ...mapGetters(this.vuexNamespaceToLoadFrom, [ 'name', 'age'])

  }
</script>

实例化一些从多个vuex命名空间加载其属性的Person多用途组件:

<Person vuex-namespace-to-load-from="api/jim">
<Person vuex-namespace-to-load-from="api/someotherpath/rachid">
<div>
 <Person vuex-namespace-to-load-from="api/alternatepeople/grace">
</div>

2 个答案:

答案 0 :(得分:2)

稍微扩展问题定义,这个

export default {
  props: ['vuexNamespaceToLoadFrom'],
  ...
  computed: {
    ...mapGetters(this.vuexNamespaceToLoadFrom, [ 'name', 'age'])
  }
}

是Vue用于创建组件实例的声明性对象,因此不能在mapGetters等帮助程序中直接使用实例属性。

但是,此讨论Generating computed properties on the fly显示了一种推迟实例属性评估的方法。

基本上,在实例完全挂载之前,不会计算计算出的get()的主体,因此对this.$storethis[namespaceProp]的引用将在此处起作用。

根据您的情况进行调整,

辅助功能

function mapWithRuntimeNamespace({namespaceProp} = {}, props = []) {
  return props.reduce((obj, prop) => {
    const computedProp = {
      get() {
        return this.$store.getters[this[namespaceProp] + '/' + prop]
      }
    }
    obj[prop] = computedProp
    return obj
  }, {})
}

<强>使用

export default {
  props: ['vuexNamespaceToLoadFrom'],
  ...
  computed: {
    ...mapWithRuntimeNamespace(
      { namespaceProp: 'vuexNamespaceToLoadFrom' }, 
      ['name', 'age']
    )
  }
}

答案 1 :(得分:0)

这个怎么样?

人员组成部分:

export default (vuexNamespace) => ({
  ...mapGetters(vuexNamespace, ['name', 'age']) 
})

父组件:

export default {
  components: {
    Person: Person('someNamespace')
  }
}

没有测试它,但我认为它应该工作:)