At NOVA LAB, every system has its own configuration protocol. Pinia offers two styles for defining stores - Composition API (setup function) and Options API. Composition API is recommended because it's closer to how we write Vue 3 components.
1// Composition API (RECOMMENDED)
2export const useCounterStore = defineStore('counter', () => {
3 const count = ref(0)
4 const doubleCount = computed(() => count.value * 2)
5 function increment() { count.value++ }
6
7 return { count, doubleCount, increment }
8})
9
10// Options API
11export const useCounterStore = defineStore('counter', {
12 state: () => ({ count: 0 }),
13 getters: {
14 doubleCount: (state) => state.count * 2
15 },
16 actions: {
17 increment() { this.count++ }
18 }
19})| Aspect | Composition API | Options API | |--------|----------------|-------------| | Flexibility | Full | Limited | | TypeScript | Natural typing | Requires declarations | |
$reset() | Must define manually | Works automatically |
| Composables | Easy to use | More difficult |
| Syntax | Like <script setup> | Like Vue Options API |Composition API allows easy use of composables inside a store:
1import { defineStore } from 'pinia'
2import { ref, computed, watch } from 'vue'
3import { useLocalStorage } from '@vueuse/core'
4
5export const useSettingsStore = defineStore('settings', () => {
6 // Composable inside a store!
7 const theme = useLocalStorage('theme', 'dark')
8 const language = useLocalStorage('language', 'en')
9
10 const isDark = computed(() => theme.value === 'dark')
11
12 function toggleTheme() {
13 theme.value = isDark.value ? 'light' : 'dark'
14 }
15
16 return { theme, language, isDark, toggleTheme }
17})You can use
watch and watchEffect inside a store:1export const useAlertStore = defineStore('alerts', () => {
2 const temperature = ref(22)
3 const alerts = ref([])
4
5 // Watcher reacting to changes
6 watch(temperature, (newTemp, oldTemp) => {
7 if (newTemp > 50) {
8 alerts.value.push({
9 type: 'critical',
10 message: `Temperature critical: ${newTemp}°C`,
11 timestamp: Date.now()
12 })
13 }
14 })
15
16 function setTemperature(value) {
17 temperature.value = value
18 }
19
20 return { temperature, alerts, setTemperature }
21})1interface CrewMember {
2 id: number
3 name: string
4 role: 'commander' | 'engineer' | 'scientist'
5 active: boolean
6}
7
8export const useCrewStore = defineStore('crew', () => {
9 const members = ref<CrewMember[]>([])
10 const selected = ref<CrewMember | null>(null)
11
12 const activeMembers = computed<CrewMember[]>(() =>
13 members.value.filter(m => m.active)
14 )
15
16 function addMember(member: Omit<CrewMember, 'id'>): CrewMember {
17 const newMember: CrewMember = {
18 ...member,
19 id: Date.now()
20 }
21 members.value.push(newMember)
22 return newMember
23 }
24
25 return { members, selected, activeMembers, addMember }
26})