mapState, mapGetters, mapMutations and mapActions with Vue3/Vuex4 and script setup
Published here first: https://medium.com/geekculture/mapgetters-with-vue3-vuex4-and-script-setup-5827f83930b4
I just stumbled upon this StackOverflow post while checking out Vue 3 and this new syntax and Composition API and so on and getting to the point where I was ready to add a Vuex store.
In Vue 2…
…populating a component with properties from store getters looked like this:
<template>
<div>
{{ count }}
{{ countIsOdd }}
{{ countIsEven }}
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['count', 'countIsOdd', 'countIsEven'])
}
}
</script>
In Vue 3…
…according to the docs, it looks like this and with the <script setup> syntax it looks like this:
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
const store = useStore()
const count = computed(() => store.getters.count)
const countIsOdd = computed(() => store.getters.countIsOdd)
const countIsEven = computed(() => store.getters.countIsEven)
</script>
This actually looks totally fine to me but one might argue that computed(() => store.getters. is repeated with every line and that doesn’t look so nice. So…
What I did…
… I added a file called lib.js:
import { computed } from 'vue'
import { useStore } from 'vuex'
const mapGetters = () => {
const store = useStore()
return Object.fromEntries(
Object.keys(store.getters).map(
getter => [getter, computed(() => store.getters[getter])]
)
)
}
export { mapGetters }
And then the component looks like this:
<template>
<div>
{{ count }}
{{ countIsOdd }}
{{ countIsEven }}
</div>
</template>
<script setup>
import { mapGetters } from '../lib'
const { count, countIsOdd, countIsEven } = mapGetters()
</script>
Works for me and I felt like sharing this. The same can be applied to actions and mutations of course and to submodules in your store. I just didn’t need that yet so I didn’t implement it.
Well… Ok. 5 Minutes after writing that, I actually added a mapMutations function in lib.js. :D
const mapMutations = () => {
const store = useStore()
return Object.fromEntries(
Object.keys(store._mutations).map(
mutation => [mutation, value => store.commit(mutation, value)]
)
)
}
export { mapGetters, mapMutations }
And in the component:
<script setup>
import { mapGetters, mapMutations } from '../lib'
const { count } = mapGetters()
const { countUp, countDown } = mapMutations()
</script>
I’m not sure if I overlook some unwanted side effects in this but for now, it does what I want.
My final result:
import { computed } from 'vue'
import { useStore } from 'vuex'
const mapState = () => {
const store = useStore()
return Object.fromEntries(
Object.keys(store.state).map(
key => [key, computed(() => store.state[key])]
)
)
}
const mapGetters = () => {
const store = useStore()
return Object.fromEntries(
Object.keys(store.getters).map(
getter => [getter, computed(() => store.getters[getter])]
)
)
}const mapMutations = () => {
const store = useStore()
return Object.fromEntries(
Object.keys(store._mutations).map(
mutation => [mutation, value => store.commit(mutation, value)]
)
)
}
const mapActions = () => {
const store = useStore()
return Object.fromEntries(
Object.keys(store._actions).map(
action => [action, value => store.dispatch(action, value)]
)
)
}
export { mapState, mapGetters, mapMutations, mapActions }
…and in the component:
<template>
Count: {{ count }}
Odd: {{ counterIsOdd }}
Even: {{ counterIsEven }}
<button @click="countUp">count up</button>
<button @click="countDown">count down</button>
<button @click="getRemoteCount('https://api.countapi.xyz')">
get remote count
</button>
</template>
<script setup>
import { mapState, mapGetters, mapMutations, mapActions } from '../lib'
// computed properties
const { count } = mapState()
const { countIsOdd, countIsEvent } = mapGetters()
// commit/dispatch functions
const { countUp, countDown } = mapMutations()
const { getRemoteCount } = mapActions()
</script>
Leave mapState, mapGetters, mapMutations and mapActions with Vue3/Vuex4 and script setup to:
Read more #web posts
Best Posts From mkt
We have not curated any of mkt's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From mkt
- Ethereum on GitHub
- mapState, mapGetters, mapMutations and mapActions with Vue3/Vuex4 and script setup
- Regular Expressions for Non-Programmers.
- Make GitHub Workflows run consecutively
- Multiple Environments With GitHub Pages
- GitHub Pages with Dynamic Routes
- Petrinja Earthquake
- Random Thought
- Random Thought
- Random Thought