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

Computed i Watch w Praktyce - Systemy Misji

Połączmy wiedzę w praktycznych przykładach systemów NOVA LAB.

System Wyszukiwania Modułów z Debounce

1<template>
2  <div class="module-search-system" style="background: #0a0e27; color: #00ff88;">
3    <input v-model="searchInput" placeholder="Szukaj modułów..." style="background: #1a1e37; color: #00ff88;" />
4    <p v-if="isLoading" style="color: #00b4d8;">Skanowanie bazy NOVA LAB...</p>
5    <ul>
6      <li v-for="item in results" :key="item.id" style="border-bottom: 1px solid #00b4d8;">
7        {{ item.name }}
8      </li>
9    </ul>
10  </div>
11</template>
12
13<script setup>
14import { ref, watch } from 'vue'
15
16const searchInput = ref('')
17const searchQuery = ref('')
18const results = ref([])
19const isLoading = ref(false)
20
21// Debounce - opóźnij wyszukiwanie
22let debounceTimeout
23watch(searchInput, (value) => {
24  clearTimeout(debounceTimeout)
25  debounceTimeout = setTimeout(() => {
26    searchQuery.value = value
27  }, 300)
28})
29
30// Wykonaj wyszukiwanie
31watch(searchQuery, async (query) => {
32  if (!query) {
33    results.value = []
34    return
35  }
36
37  isLoading.value = true
38
39  try {
40    const response = await fetch(`/api/nova-lab/modules?q=${query}`)
41    results.value = await response.json()
42  } finally {
43    isLoading.value = false
44  }
45})
46</script>

Kalkulator Trajektorii z Historią

1<template>
2  <div class="trajectory-calc" style="background: #0a0e27; color: #00ff88;">
3    <label>Prędkość (km/s):</label>
4    <input v-model.number="velocity" type="number" style="background: #1a1e37; color: #00ff88;" />
5
6    <label>Operacja:</label>
7    <select v-model="operation" style="background: #1a1e37; color: #00ff88;">
8      <option value="+">Dodaj</option>
9      <option value="-">Odejmij</option>
10      <option value="*">Mnóż</option>
11      <option value="/">Dziel</option>
12    </select>
13
14    <label>Czas (s):</label>
15    <input v-model.number="time" type="number" style="background: #1a1e37; color: #00ff88;" />
16    <p style="color: #00b4d8;">= {{ result }}</p>
17
18    <h3>Historia obliczeń:</h3>
19    <ul>
20      <li v-for="(entry, i) in history" :key="i" style="color: #00b4d8;">{{ entry }}</li>
21    </ul>
22  </div>
23</template>
24
25<script setup>
26import { ref, computed, watch } from 'vue'
27
28const velocity = ref(25)
29const time = ref(3600)
30const operation = ref('*')
31const history = ref([])
32
33const result = computed(() => {
34  switch (operation.value) {
35    case '+': return velocity.value + time.value
36    case '-': return velocity.value - time.value
37    case '*': return velocity.value * time.value
38    case '/': return time.value !== 0 ? velocity.value / time.value : 'Error'
39    default: return 0
40  }
41})
42
43// Zapisuj do historii obliczeń
44watch(result, (newResult) => {
45  const entry = `${velocity.value} ${operation.value} ${time.value} = ${newResult}`
46  history.value.unshift(entry)
47
48  // Ogranicz do 10 wpisów
49  if (history.value.length > 10) {
50    history.value.pop()
51  }
52})
53</script>

Walidacja Formularza

1<template>
2  <form @submit.prevent="submit">
3    <div>
4      <input v-model="email" placeholder="Email" />
5      <span v-if="emailError" class="error">{{ emailError }}</span>
6    </div>
7
8    <div>
9      <input v-model="password" type="password" placeholder="Hasło" />
10      <div class="strength" :class="passwordStrengthClass">
11        Siła hasła: {{ passwordStrength }}
12      </div>
13    </div>
14
15    <button :disabled="!isFormValid">Zarejestruj</button>
16  </form>
17</template>
18
19<script setup>
20import { ref, computed } from 'vue'
21
22const email = ref('')
23const password = ref('')
24
25const emailError = computed(() => {
26  if (!email.value) return ''
27  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
28  return regex.test(email.value) ? '' : 'Nieprawidłowy email'
29})
30
31const passwordStrength = computed(() => {
32  const pwd = password.value
33  if (pwd.length < 6) return 'Słabe'
34  if (pwd.length < 10) return 'Średnie'
35  if (/[A-Z]/.test(pwd) && /[0-9]/.test(pwd)) return 'Silne'
36  return 'Średnie'
37})
38
39const passwordStrengthClass = computed(() => ({
40  weak: passwordStrength.value === 'Słabe',
41  medium: passwordStrength.value === 'Średnie',
42  strong: passwordStrength.value === 'Silne'
43}))
44
45const isFormValid = computed(() => {
46  return email.value &&
47         !emailError.value &&
48         password.value.length >= 6
49})
50
51function submit() {
52  console.log('Formularz wysłany')
53}
54</script>
Przejdź do CodeWorlds