We use cookies to enhance your experience on the site
CodeWorlds

Pinia Basics

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.

What is Pinia?

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:

  • Simpler syntax than Vuex (no mutations!)
  • Full TypeScript support
  • Great integration with Vue DevTools
  • Modular architecture - multiple independent stores

Installation and Setup

To start Pinia, we need two steps - install the package and connect it to the application:

1npm install pinia
1// 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.

Defining a Store - defineStore

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
.

Using the Store in a Component

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>

storeToRefs - Reactive Destructuring

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>
Go to CodeWorlds