Pinia for State Management
Using Pinia for state management in Vue appsโ
๐ What is Pinia?โ
Pinia allows you to store data and methods (aka variables and functions) in a central way, and import them to different components throughout your app. This can simplify your code by importing and using variables and functions only in the components where they are needed. This avoids prop drilling and several layers of callback functions!
Here is the documentation. ๐
When to use it?โ
โ ย Use Pinia to store any data and methods that need to be accessible across multiple components. Ex:
myDataneeds to be set inComponent.vue, but displayed inSiblingComponent.vueComponent.vueneeds to fetch data based on some action in that component, butSiblingComponent.vueneeds to display, edit or remove the same data.myDataandotherDataare rendered in different components, but are both used in a third component to calculate some outcome.
โย Do not use Pinia for data that is only used temporarily, or in a single component. Ex:
Component.vuetemporarily sets aselectedItem- some function is performed on the selected item, then it clears when a new item is selected.Component.vueusesspecificDatathat never needs to be passed to or used in other components.
How to use it?โ
Create a store ๐๏ธโ
First, create your store file and name it with this pattern: useExampleStore.js
- i.e.
use+YourStoreName+Store - so for example, for RMT's disease status data:
useDiseaseStatusStore.js
Step-by-step instructions in comments below.
You can look at examples in the codebase in client > src > stores.
// ******* STEP 1: import defineStore at the top *******
import { defineStore } from "pinia";
// ******* STEP 2: export your store, and after defineStore, give your store a unique descriptive name *******
export const useExampleStore = defineStore("example", {
// ******* STEP 3: define your data/variables in state *******
state: () => ({
myVariable: [],
anotherVariable: "I โค๏ธ Pinia",
}),
// ******* STEP 4: define your functions/methods in "actions" *******
actions: {
async myFunction(params) {
// your code...
},
anotherFunction() {
// your code...
},
},
});
// ******* THAT'S IT! Congrats :) *******
Use a store ๐งคโ
Hereโs a ๐ฌย how-to video
Process to use stored data or methods in any component is:
- In
<script>, import:- the correct store
mapStateif youโre using data/variablesmapActionsif youโre using functions/methods
import { useExampleStore } from "@/stores/useExampleStore";
import { mapState, mapActions } from "pinia";
- For data/variables, add a
computedproperty in your<script>, and usemapStateto destructure your stored data:
computed: {
...mapState(useExampleStore, ['myVariable', 'anotherVariable'])
},
- For functions/methods, use
mapActionsin yourmethodsto destructure the stored functions. You do not need to include params, just function names:
methods: {
...mapActions(useExampleStore, ['myFunction', 'anotherFunction'])
},
- Then you can use as usual! i.e. Use the variables in your
<template>, call the functions, etc., with the same syntax as if they were standarddataormethods.
<div>
<select @change="myFunction(value)">
<option v-for="item in myVariable" :key="item.id" :value="item.name">
{{ item.name }}
</option>
</select>
</div>
