Welcome to the NOVA LAB Central Database! Year 2087 - this is where we store all critical data from the Mars mission. Just as the base's main computer stores information about systems, crew, and resources, Pinia stores the global state of a Vue application.
Pinia is the official state management library for Vue 3. It is the successor to Vuex and offers much simpler syntax. Think of it as the central computer of NOVA LAB - a single control point from which all station modules retrieve data.
Main advantages of Pinia:
To start Pinia, we need two steps - install the package and connect it to the application:
1npm install pinia1// main.js
2import { createApp } from 'vue'
3import { createPinia } from 'pinia'
4import App from './App.vue'
5
6const pinia = createPinia()
7const app = createApp(App)
8
9app.use(pinia)
10app.mount('#app')The
createPinia() function creates a Pinia instance, and app.use(pinia) registers it as a Vue plugin. From this point on, all stores are available throughout the application.A store is created using
defineStore. It takes two arguments: a unique store name and a setup function (Composition API style):1// stores/mission.js
2import { defineStore } from 'pinia'
3import { ref, computed } from 'vue'
4
5export const useMissionStore = defineStore('mission', () => {
6 // State - reactive data
7 const missionName = ref('Mars Exploration Alpha')
8 const status = ref('active')
9 const crewCount = ref(6)
10
11 // Getters - computed values
12 const statusLabel = computed(() =>
13 status.value === 'active' ? 'ACTIVE' : 'INACTIVE'
14 )
15
16 // Actions - functions that modify state
17 function updateStatus(newStatus) {
18 status.value = newStatus
19 }
20
21 // Return everything that should be accessible
22 return {
23 missionName,
24 status,
25 crewCount,
26 statusLabel,
27 updateStatus
28 }
29})Naming convention:
useXxxStore - prefix use and suffix Store.1<script setup>
2import { useMissionStore } from '@/stores/mission'
3
4const missionStore = useMissionStore()
5
6// Access state
7console.log(missionStore.missionName)
8
9// Call an action
10missionStore.updateStatus('completed')
11</script>
12
13<template>
14 <div>
15 <h1>{{ missionStore.missionName }}</h1>
16 <p>Status: {{ missionStore.statusLabel }}</p>
17 <button @click="missionStore.updateStatus('paused')">
18 Pause Mission
19 </button>
20 </div>
21</template>Regular destructuring loses reactivity. Use
storeToRefs for state and getters:1<script setup>
2import { useMissionStore } from '@/stores/mission'
3import { storeToRefs } from 'pinia'
4
5const store = useMissionStore()
6
7// State and getters - storeToRefs (preserves reactivity)
8const { missionName, status, statusLabel } = storeToRefs(store)
9
10// Actions - regular destructuring (they're functions, not refs)
11const { updateStatus } = store
12</script>