Specify Vuex Store To Use In Component

I have modularized/namespaced my Vuex store and need child-components to be able to access data/use the same stores as their parent component.

Here’s what I’ve tried:

<!-- ParentOne.vue -->
<template>
<div>
  <child-component
    vuex-store="services/opportunities"
  />
</div>
</template>

<script>
import ChildComponent from '@/components/services/child-components/ChildComponent';
import { mapActions, mapState, mapGetters } from 'vuex';

export default {
    components: {
        'child-component': ChildComponent,
    },

    computed: {
        ...mapState('services/opportunities', {
            statusListOpportunities: 'statusListOpportunities',
        }),
    }
}
</script>
<!-- ChildComponent.vue -->
<template>
<div>
  <!-- Content -->
</div>
</template>

<script>
import { mapActions, mapState, mapGetters } from 'vuex';

export default {
    props: {
        vuexStore: {
            type: String,
        },
    },

    computed: {
        ...mapState(this.vuexStore, {
            statusListOpportunities: 'statusListOpportunities',
        }),
    }
}
</script>

And here’s the error I’m getting

Uncaught TypeError: Cannot read property ‘vuexStore’ of undefined

I’ve been passing down props, but the prop juggling is getting chaotic and it would be much easier if I could just specify which store a component should use.

I also not able to specify the store directly in the child component since ParentTwo.vue may use a different store such as services/cases.

Anyone have any idea why this wouldn’t work. I’m open to alternative solutions as well.

Could it be that you need to use a function in the mapState options?
The example here shows a use of “this”.

Your code is effectively equivalent to this:

const moduleName = this.vuexStore

const mappedState = mapState(moduleName, {
  statusListOpportunities: 'statusListOpportunities',
})

export default {
  props: {
    vuexStore: {
      type: String,
    },
  },

  computed: {
    ...mappedState
  }
}

As it isn’t surrounded by a function, the this in this.vuexStore will be the this from the root scope, which is undefined. It won’t be the component instance.

It’s a bit fiddly to implement it without mapState because you’re relying on that to parse the namespace path. Similarly, it’s also a bit fiddly to implement it with mapState because the path isn’t known till runtime. The best I could come up with is this:

computed: {
  moduleState () {
    let state = this.$store.state

    for (const name of this.vuexStore.split('/')) {
      if (name) {
        state = state[name]
      }
    }

    return state
  },

  statusListOpportunities () {
    return this.moduleState.statusListOpportunities
  }
}

I get the feeling that the reason this is so difficult is because it isn’t the right approach. I’ve not come across the idea of passing around module names like this. That said, it would be much easier if the modules weren’t nested because there’d be no need to parse the namespace path.