I have a component that should display data from the store, but the component is reusable, so I would like to pass the name of the store module and property name via props, like so:
<thingy module="module1" section="person">
Then, in 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 problem is, it seems the props are undefined at the time when mapState()
is executed. If I hardcode the prop values, the component works. Also, if I log the props in the created()
hook, I get the expected values. So it seems like a race condition.
Am I going about this the wrong way here?
Update
The module namespace must be passed from within the mapping function, 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`);
}
})
(note that get()
is a lodash, not a vue function)
This can be further abstracted into a mixin.
Note the comment in the mapState example
:
// to access local state with `this`, a normal function must be used countPlusLocalState (state) { return state.count + this.localCount }
You are using arrow functions.
As for this.module
, I think you're going to have to forego the binding helper notation and explicitly put the module reference into the definitions. I'm guessing that looks like:
computed: mapState(this.module, {
title(state) {
return get(`${state}.${this.module}`, `${this.section}.title`);
},
message(state) {
return get(`${state}.${this.module}`, `${this.section}.message`);
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With