Vuex 4 isn’t terribly different from previous versions, but it is the only version compatible with Vue 3. See how to use them together.
Vuex is the preferred state management solution for Vue apps, and Vuex 4 is the version compatible with Vue 3. Let’s explore how to use Vuex 4 with Vue 3.
We can install Vuex with Vue 3 in a few ways, one of which is to use the script tag.
To use it, 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++;
}
}
});
const app = Vue.createApp({
methods: {
increment() {
this.$store.commit("increment");
}
},
computed: {
count() {
return this.$store.state.count;
}
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
Above, we add the scripts for Vuex 4 and Vue, and then we can use the Vuex global object in our code.
To create a store, we call the Vuex.Store
constructor with an object with the states and mutations that we want to add to create a basic store. States are properties that stores data in our Vuex store; they let us access the data from anywhere in our Vue 3 app. Mutations are functions that lets us modify states in the Vuex store.
Once we’ve created our store, we pass it into the Vue.createApp
method to add the store to our app. The app.use(store);
method call lets us use the store in our Vue 3 app.
Now that the store has been added, we can use the this.$store
property to get the states and manipulate our store. The this.$store.commit
method lets us commit the mutations to the store.
We commit the increment
mutation in our store to update the count
state. Therefore, when we click the increment button, the count
Vuex state will be updated along with the count
computed property.
To add store states into our app more easily, we can use getters. Getters are functions that returns a state, or states that have been operated on or combined with other values.
For example, we can add a getter by writing:
<!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>{{doubleCount}}</p>
</div>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
getters: {
doubleCount: (state) => {
return state.count * 2;
}
}
});
const app = Vue.createApp({
methods: {
increment() {
this.$store.commit("increment");
}
},
computed: {
...Vuex.mapGetters(["doubleCount"])
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
We added the doubleCount
getter, which returns the count
state multiplied by two. Then, in the component, we call the Vuex.mapGetters
method with the name of the getter to map it to a computed property. We also have it in the template so we can see its value.
If we want a method as a getter, we can return a function in our getter. For instance, 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">
<div>
<p>{{getTodoById(1).text}}</p>
</div>
</div>
<script>
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: "drink", done: true },
{ id: 2, text: "sleep", done: false }
]
},
getters: {
getTodoById: (state) => (id) => {
return state.todos.find((todo) => todo.id === id);
}
}
});
const app = Vue.createApp({
computed: {
...Vuex.mapGetters(["getTodoById"])
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
We have the todos
Vuex store state, and we want to get an entry from it by its id
property value. To do that, we have the getTodosById
getter method, which returns a function. The function subsequently returns the entry from the state.todos
array by calling find
to get the value by its id
value.
In the component, we call Vuex.mapGetters
the same way to map the method to a computed property.Then we can call the function it returns to get the to-do item by its id
value. Therefore, 'drink'
should be displayed on the browser screen since this has id: 1
.
We’ve already seen a mutation in the previous examples; it’s just a method we can use to modify a state.
A mutation method can take a payload, which can be used to modify a state value. 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, n) {
state.count += n;
}
}
});
const app = Vue.createApp({
methods: {
increment() {
this.$store.commit("increment", 5);
}
},
computed: {
count() {
return this.$store.state.count;
}
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
Our increment
mutation method has an n
parameter that is used to increase the value of the count
state. Then, we call the this.$store.commit
method with a second argument to pass in the value to the increment
method. n
should now be 5
, so the count
Vuex state would be incremented by five.
We can pass in an object to the this.$store.commit
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, { amount }) {
state.count += amount;
}
}
});
const app = Vue.createApp({
methods: {
increment() {
this.$store.commit({
type: "increment",
amount: 5
});
}
},
computed: {
count() {
return this.$store.state.count;
}
}
});
app.use(store);
app.mount("#app");
</script>
</body>
</html>
We called this.$store.commit
with an object with the type
and amount
properties.
The type
property is used to find the name of the mutation method to call. So, we’ll call the increment
mutation method since that’s the value of type
. The other properties will be passed in with the object that we pass as the second argument of the increment
method.
So we get the amount
property from the second parameter of increment
and use that to update the Vuex store’s count
state.
#vue #vuex #javascript #programming #developer