Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Kompozycja Stores

W NOVA LAB różne systemy stacji muszą ze sobą współpracować - system tlenu komunikuje się z systemem alarmowym, a system nawigacji z systemem komunikacji. Podobnie w Pinia - stores mogą importować i używać innych stores.

Store używający innego store

1// stores/auth.js
2import { defineStore } from 'pinia'
3import { ref, computed } from 'vue'
4
5export const useAuthStore = defineStore('auth', () => {
6  const user = ref(null)
7  const token = ref(null)
8
9  const isAuthenticated = computed(() => !!token.value)
10  const userName = computed(() => user.value?.name || 'Guest')
11
12  async function login(credentials) {
13    const res = await fetch('/api/login', {
14      method: 'POST',
15      headers: { 'Content-Type': 'application/json' },
16      body: JSON.stringify(credentials)
17    })
18    const data = await res.json()
19    token.value = data.token
20    user.value = data.user
21  }
22
23  function logout() {
24    user.value = null
25    token.value = null
26  }
27
28  return { user, token, isAuthenticated, userName, login, logout }
29})
1// stores/missions.js - używa auth store
2import { defineStore } from 'pinia'
3import { ref } from 'vue'
4import { useAuthStore } from './auth'
5
6export const useMissionsStore = defineStore('missions', () => {
7  const missions = ref([])
8
9  async function fetchMissions() {
10    // Użyj auth store do pobrania tokena
11    const authStore = useAuthStore()
12
13    if (!authStore.isAuthenticated) {
14      throw new Error('Must be logged in')
15    }
16
17    const res = await fetch('/api/missions', {
18      headers: {
19        'Authorization': `Bearer ${authStore.token}`
20      }
21    })
22
23    missions.value = await res.json()
24  }
25
26  return { missions, fetchMissions }
27})

Wzajemne zależności stores

Stores mogą nawzajem się używać, ale wywołuj

useStore()
wewnątrz actions (nie na górze setup function), aby uniknąć problemów z cyklicznymi zależnościami:

1// stores/notifications.js
2import { defineStore } from 'pinia'
3import { ref } from 'vue'
4
5export const useNotificationStore = defineStore('notifications', () => {
6  const notifications = ref([])
7
8  function add(message, type = 'info') {
9    notifications.value.push({
10      id: Date.now(),
11      message,
12      type,
13      timestamp: new Date()
14    })
15  }
16
17  function remove(id) {
18    notifications.value = notifications.value.filter(n => n.id !== id)
19  }
20
21  return { notifications, add, remove }
22})
23
24// stores/resources.js - używa notifications
25import { useNotificationStore } from './notifications'
26
27export const useResourceStore = defineStore('resources', () => {
28  const oxygen = ref(100)
29
30  function consumeOxygen(amount) {
31    oxygen.value -= amount
32
33    if (oxygen.value < 20) {
34      // Wywołaj useStore WEWNĄTRZ action
35      const notifStore = useNotificationStore()
36      notifStore.add('Oxygen level critical!', 'danger')
37    }
38  }
39
40  return { oxygen, consumeOxygen }
41})

Architektura wielu stores

Zaleca się tworzenie wielu małych, specjalizowanych stores zamiast jednego dużego:

1stores/
2├── auth.js         # Autoryzacja użytkownika
3├── resources.js    # Zasoby stacji (tlen, woda, energia)
4├── crew.js         # Dane załogi
5├── missions.js     # Misje i zadania
6├── notifications.js # System powiadomień
7└── settings.js     # Ustawienia aplikacji

Każdy store odpowiada za jeden "moduł" aplikacji - tak jak każdy moduł stacji NOVA LAB ma swoją funkcję.

Przejdź do CodeWorlds