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

Projekt Główny: Typowany Panel Stacji NOVA LAB

Czas połączyć całą wiedzę z tego modułu! Stworzymy typowany panel sterowania stacją kosmiczną NOVA LAB, który wykorzystuje TypeScript z Vue 3 i uwzględnia koncepcje SSR.

Wymagania projektu

Nasz panel sterowania powinien zawierać:

  1. Typowane propsy — każdy komponent deklaruje jakie dane przyjmuje
  2. Typowane emity — zdarzenia są precyzyjnie zdefiniowane
  3. Typowane ref i reactive — stan aplikacji jest w pełni typowany
  4. Template refs — do bezpośredniej interakcji z DOM
  5. Provide/Inject — do przekazywania konfiguracji stacji

Architektura aplikacji

1// types.ts — centralne typy aplikacji
2interface CrewMember {
3  id: number
4  name: string
5  role: 'commander' | 'engineer' | 'scientist' | 'pilot'
6  active: boolean
7}
8
9interface StationModule {
10  id: string
11  name: string
12  status: 'online' | 'offline' | 'maintenance'
13  power: number
14}
15
16interface StationState {
17  name: string
18  crew: CrewMember[]
19  modules: StationModule[]
20  alerts: Alert[]
21}
22
23interface Alert {
24  id: number
25  level: 'info' | 'warning' | 'critical'
26  message: string
27  timestamp: Date
28}

Komponent ModuleCard z typami

1<script setup lang="ts">
2interface ModuleCardProps {
3  module: StationModule
4  isSelected?: boolean
5}
6
7const props = withDefaults(defineProps<ModuleCardProps>(), {
8  isSelected: false
9})
10
11const emit = defineEmits<{
12  select: [moduleId: string]
13  togglePower: [moduleId: string, newStatus: boolean]
14}>()
15</script>

Panel z Provide/Inject

1<script setup lang="ts">
2import { provide, reactive, type InjectionKey } from 'vue'
3
4interface StationConfig {
5  name: string
6  sector: string
7  year: number
8}
9
10const StationKey: InjectionKey<StationConfig> = Symbol('Station')
11
12provide(StationKey, {
13  name: 'NOVA LAB',
14  sector: 'Alpha-7',
15  year: 2087
16})
17</script>

Uwzględnienie SSR

Tworząc aplikację z myślą o SSR (np. z Nuxt), pamiętaj:

1// NIE używaj obiektów przeglądarki poza onMounted
2import { onMounted, ref } from 'vue'
3
4const windowWidth = ref(0)
5
6// DOBRZE — window dostępne tylko na kliencie
7onMounted(() => {
8  windowWidth.value = window.innerWidth
9})
10
11// ZLE — window nie istnieje na serwerze!
12// const width = window.innerWidth  // BLAD w SSR

Composable przyjazny SSR:

1function useScreenSize() {
2  const width = ref(0)
3  const height = ref(0)
4
5  onMounted(() => {
6    width.value = window.innerWidth
7    height.value = window.innerHeight
8
9    window.addEventListener('resize', () => {
10      width.value = window.innerWidth
11      height.value = window.innerHeight
12    })
13  })
14
15  return { width, height }
16}

Pełny przykład

Poniżej znajduje się interaktywny edytor z typowaną aplikacją Vue. Przeanalizuj kod i eksperymentuj z typami — dodaj nowe właściwości, zmień typy i obserwuj jak TypeScript pomaga wykrywać błędy.

Przejdź do CodeWorlds