When you think about state management in Vue, you will most likely be thinking about two particular state management libraries: Pinia and Vuex. Pinia is the newer state management library of the two. In this article, we will look at what they are and some of the differences between the two libraries.
With Pinia becoming very popular, it is the official state management library for Vue.js. Named after piƱa (Spanish name for a pineapple). It is lightweight and uses the reactivity system in Vue 3. You can consider Pinia to be Vuex 5 with a different name, according to the Vuex documentation.
A pineapple is in reality a group of individual flowers that join together to create a multiple fruit. Similar to stores, each one is born individually, but they are all connected at the end. ~ Pinia documentation
Being the official state management library, you will have the option to include it in your application when you create a new Vue.js App. Alternatively, you can install it through NPM or Yarn:
npm install pinia # or 'yarn add pinia'
After installing the package, you will need to create and include a Pinia instance in your main.js
file. This instance is the root store:
// Vue 3
import { createApp } from "vue";
import { createPinia } from "pinia"; // add this
import App from "./App.vue";
const pinia = createPinia(); // add this
const app = createApp(App);
app.use(pinia); // add this
app.mount("#app");
From here, you can proceed to create stores for your web app like this:
// stores/counter.js
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => {
return { count: 0 };
},
// could also be defined as
// state: () => ({ count: 0 })
actions: {
increment() {
this.count++;
},
},
});
And import it in a component like this:
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
counter.count++
counter.increment()
</script>
<template>
<div>Count: {{ counter.count }}</div>
</template>
For more information on creating stores or installation including Vue 2 and Nuxt, you can see the documentation.
The Pinia API is simple and intuitive, meaning that it is very easy to understand because you do not have to think very hard about how it works.
It has proper TypeScrpit support and autocompletion for JS users. In Vuex, it can be tough to get it to support types.
There is a timeline to track actions and mutations. Also, stores appear in components where they are used.
In Pinia, you create multiple stores and import them directly in components which need them. In Vuex, you would have one store which has the app state inside it. Having multiple stores simplifies development since you only use the ones you need rather than having to use the entire store.
Vuex was the previous official state management pattern + library for Vue.js applications. It serves as a centralized store for a Vue.js App. Vuex (3 and 4) is in maintenance mode, meaning it is highly unlikely it will get new features. It will however, continue to be maintained.
You can install it using NPM or Yarn:
npm install vuex@next --save # or 'yarn add vuex@next --save'
You can then create a Vuex store like this:
import { createApp } from "vue";
import { createStore } from "vuex";
// Create a new store instance.
const store = createStore({
state() {
return {
count: 0,
};
},
mutations: {
increment(state) {
state.count++;
},
},
});
const app = createApp({
/* your root component */
});
// Install the store instance as a plugin
app.use(store);
You can read more on Vuex here.
If you already have a project where you are using Vuex, I would say you can continue using it for that project. For new projects, Pinia is the new default and is recommended.