How to use Pinia in Vue application

Pinia is a store library for Vue, it allows you to share a state across components/pages. Pinia is going to replace Vuex. It removes the Mutations in Vuex. Pinia works for both Vue 2 and Vue 3 and doesn’t require you to use the composition API. This article shows the steps of how to use Pinia.
- Install Pinia
Run yarn install or nvm install to install Pinia
yarn add pinia
# or with npm
npm install pinia
- Import Pinia
Import Pinia in the entry point javascript file and register it to the Vue component.
// main.js or application.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
If there are multiple entry point javascript files for different components or pages us Pinia, We could import Pinia in a file first ( for example, index.js
).
// ../store/index.js
import { createPinia } from 'pinia';
// 創建 pinia
const pinia = createPinia();
export default pinia;
And then import the file ( for example, index.js
) into each entry point javascript file that uses Pinia.
// home.js
import { createApp } from 'vue/dist/vue.esm-bundler';
import Home from '../components/Home.vue';
import pinia from '../store/index.js';
const app = createApp(Home, railsProps);
app.use(pinia);
app.mount('#app')
// api_docs.js
import { createApp } from 'vue/dist/vue.esm-bundler';
import ApiDocs from '../components/ApiDocs.vue';
import pinia from '../store/index.js';
const app = createApp(ApiDocs, railsProps);
app.use(pinia);
app.mount('#app')
- Define store
Define the store setting, and define state
, getters
, actions
in the store. The state
is defined as a function that returns the initial state. getters
are exactly the equivalent of computed values for the state of a Store. actions
are the equivalent of methods in components. The details about the defined store can be found in Pinia Guide.
For example, we could define a counter
which value is 1 in state
, define doubleCount
which value is the double time of counter in getters and a function increment
which could increase the value of counter
. The counter
, doubleCount
and increment
could be used in the Vue component which imports Pinia and the store.
// ../store/main.js
import { defineStore } from 'pinia';
export const useStore = defineStore('usestore', {
state: () => ({
counter: 1,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
actions: {
increment() {
this.counter++;
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random());
}
},
})
- Use store
The way to use Pinia store in the Vue component is to use the mapState
, mapAction
function in Pinia and import the store we define. The mapState
get the variables defined in the store, and the mapAction
get the functions defined in the store. (The details about mapState
and mapAction
)
For example, mapState
get counter
directly, and it also allows counter
assigned to a different name variable storeCounter
. It also could calculate the counter
into a new value and assign it to a different name variable double
. mapActions
get increment
, so we could directly use it in the Vue component. Following is an example code of using the mapState
and mapActions
in a Vue component.
<template>
<div>
<div>counter: {{counter}}</div>
<div>storeCounter: {{storeCounter}}</div>
<div>double: {{double}}</div>
<div>doubleCount: {{doubleCount}}</div>
<button @click="increment">+</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'pinia';
import { useStore } from '../store/main';
export default {
....
computed: {
...mapState(useStore, ['counter', 'doubleCount']),
// 與上方相同,但註冊為 this.storeCounter
...mapState(useStore, {
storeCounter: 'counter',
// 也可以 function 直接取得 store 進行複雜處理
double: store => store.counter * 2,
}),
...
methods: {
...mapActions(useStore, ['increment']),
....
}
</script>
The Vue component render on the web page is as follows. When clicking the plus button, it will trigger increment
function and increase the counter
value.
