One of the challenges I am facing is how to make a reusable component that can display data from the store. My idea is to pass the name of the store module and property name through props, as shown below:
<thingy module="module1" section="person">
Inside the component:
<template>
<h2>{{ title }}</h2>
<p>{{ message }}</p>
</template>
<script>
import { mapState } from 'vuex';
import get from 'lodash.get';
export default {
props: [
'module',
'section',
],
computed: mapState(this.module, {
title: state => get(state, `${this.section}.title`),
message: state => get(state, `${this.section}.message`),
})
}
</script>
The issue I'm encountering is that the props are undefined when mapState()
runs. If I manually set the prop values, the component works fine. When checking the props in the created()
hook, they show the correct values. It seems like there might be a race condition happening.
Could it be that I am approaching this problem in the wrong way?
Update
In order to properly access the module namespace within the mapping function, it needs to be passed as part of the computed object, like so:
computed: mapState({
title() {
return get(this.$store.state, `${this.module}.${this.section}.title`);
},
message() {
return get(this.$store.state, `${this.module}.${this.section}.message`);
}
})
(please note that get()
is a lodash function, not a vue method)
This logic can also be moved into a mixin for further abstraction.