Vuex 4 is in beta and it’s subject to change.
Vuex is a popular state management library for Vue.
Vuex 4 is the version that’s made to work with Vue 3.
In this article, we’ll look at how to use Vuex 4 with Vue 3.
Dispatching Actions in Components
We can map our actions to component methods with the mapActions
method.
For example, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
<title>App</title>
</head>
<body>
<div id="app">
<button @click="increment">increment</button>
<p>{{count}}</p>
</div>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment({ commit }) {
commit("increment");
}
}
});
const app = Vue.createApp({
methods: {
...Vuex.mapActions(["increment"])
},
computed: {
count() {
return this.$store.state.count;
}
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
We called the Vuex.mapActions
to map our actions into a method.
We can also map it to our method with a name that’s different from the action.
For example, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
<title>App</title>
</head>
<body>
<div id="app">
<button @click="add">increment</button>
<p>{{count}}</p>
</div>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment({ commit }) {
commit("increment");
}
}
});
const app = Vue.createApp({
methods: {
...Vuex.mapActions({ add: "increment" })
},
computed: {
count() {
return this.$store.state.count;
}
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
We passed in an object to Vuex.mapActions
to map the increment
action to the add
method.
The key is the method name we want to map to.
Composing Actions
Actions are often async. We can check that it’s done by returning a promise.
For example, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
<title>App</title>
</head>
<body>
<div id="app">
<button @click="increment2">increment</button>
<p>{{count}}</p>
</div>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state, amount) {
state.count += amount;
}
},
actions: {
async increment({ commit }) {
return commit("increment", 1);
},
async increment2({ commit }) {
await commit("increment", 1);
return commit("increment", 2);
}
}
});
const app = Vue.createApp({
methods: {
...Vuex.mapActions(["increment2"])
},
computed: {
count() {
return this.$store.state.count;
}
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
We have the increment2
action which dispatches the increment
action with amount 1.
And then we dispatch it again with amount 2.
Since they’re promises and we awaited the first one, they’ll run sequentially.
Conclusion
We can dispatch actions in different ways with Vuex 4.
Actions can be mapped to methods with Vuex.mapActions
.