I have a Vue component like this:
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
props: ['index'],
computed: {
...mapGetters([
'type',
'width',
'height',
'description',
'smtTagMeasureUnits',
'tagValue'
])
}
</script>
<template>
<div :class='["block","module-"+type(index), "width"+width(index), "height"+height(index)]'>
<h3>{{ description(index) }}</h3>
<div class="data">
<h1>{{ tagValue(index) }}</h1>
<h2 class="measure">{{ smtTagMeasureUnits(index) }}</h2>
</div>
</div>
</template>
<style>
...
</style>
Parameter index, which comes into component as a prop, has been successfully passed to getters:
getters: {
...
type: (state, getters) => (par) => {
return getters.widgetsConfig[par].type
},
width: (state, getters) => (par) => {
if (getters.widgetsConfig[par].width) {
return getters.widgetsConfig[par].width
} return 2
},
height: (state, getters) => (par) => {
if (getters.widgetsConfig[par].height) {
return getters.widgetsConfig[par].height
} return 1
},
...
}
Works fine, but i'm not happy with this codestyle, because getterName(index)
constantly repeats in the template part. All of my getters should carry index as a prop, so i'd like to have just getterName
in the template and something like this in the script part:
...mapGetters([
'type',
'width',
'height',
'description',
'smtTagMeasureUnits',
'tagValue'
], index)
Is it possible to achieve any codestyle improvements here?
Vuex makes use of a central state it uses to manage its store data. However, supposing we intend to use this method in other components, we would either need to extract it into a helper function and import it into all those components or follow the traditional way of copying and pasting.
The mapGetters helper simply maps store getters to local computed properties: import { mapGetters } from 'vuex' export default { // ... computed: { // mix the getters into computed with object spread operator ... mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } }
The action will commit a mutation to update the state. You can't update state directly, it needs to be handled via a mutation. To access the state, we can use a getter to fetch the current user's name. To have that name update in the Vuex store we then need to use a setter which will dispatch an action.
If you want to keep things DRY, it would make sense to leverage logic of getting item (entity that index
corresponds to) information to the store, so component only receives full data that is ready to be rendered.
Suggested solution is to create a single getter, that accepts index
as an argument and returns full list of options from getters.widgetsConfig
.
Note that if needed other getters may be re-used in order to collect necessary information into a single object.
Possible implementation:
getters: {
...
getItemByIndex: (state, getters) => (index) => {
const { type, height, width } = getters.widgetsConfig[index]
return {
type,
height,
width
}
},
}
And update component to map a single getter and use it in computed property:
computed: {
...mapGetters([
'getItemByIndex'
]),
item () {
return this.getItemByIndex(index)
}
}
And all properties will be accessible inside a template via item.type
, item.height
, item.width
, etc..
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