Kurs Vue.js · Moduł 14: Dyrektywy i pluginy

Custom Directives - Podstawy

2 min czytania
W tej lekcji5

Witaj w Centrum Dowodzenia NOVA LAB! Rok 2087 - interfejsy stacji kosmicznej wymagają precyzyjnej kontroli nad elementami DOM. Vue udostępnia Custom Directives, które pozwalają bezpośrednio manipulować elementami na poziomie niższym niż szablony.

Czym są Custom Directives?

Vue posiada wbudowane dyrektywy: v-if, v-for, v-model, v-show. Ale możesz też tworzyć własne! Custom Directives pozwalają na bezpośredni dostęp do elementu DOM - coś, czego nie możesz osiągnąć samym szablonem.

Dyrektywy to doskonałe narzędzie, gdy potrzebujesz:

  • automatycznego focusu na input
  • obsługi kliknięcia poza elementem
  • lazy-loading obrazów
  • niestandardowych tooltipów

Rejestracja globalna: app.directive()

1const app = createApp(App)
2
3app.directive('focus', {
4  mounted(el) {
5    el.focus()
6  }
7})

Teraz możesz użyć v-focus w każdym komponencie:

1<template>
2  <input v-focus placeholder="Auto-focus!" />
3</template>

Rejestracja lokalna

W komponencie możesz zarejestrować dyrektywę lokalnie:

1<script setup>
2const vHighlight = {
3  mounted(el) {
4    el.style.backgroundColor = '#00ff88'
5    el.style.padding = '4px 8px'
6    el.style.borderRadius = '4px'
7  }
8}
9</script>
10
11<template>
12  <span v-highlight>Ważny tekst</span>
13</template>

Ważna konwencja: W <script setup> dyrektywa lokalna musi mieć nazwę zaczynającą się od v (np. vHighlight), a w szablonie używamy jej jako v-highlight (camelCase zamieniane na kebab-case).

Lifecycle hooks dyrektyw

Dyrektywy mają hooki podobne do cyklu życia komponentu:

  • created - przed związaniem atrybutów elementu
  • beforeMount - przed wstawieniem elementu do DOM
  • mounted - element jest już w DOM (najczęściej używany)
  • beforeUpdate - przed aktualizacją komponentu rodzica
  • updated - po aktualizacji komponentu rodzica
  • beforeUnmount - przed usunięciem z DOM
  • unmounted - element usuniety z DOM
1app.directive('log', {
2  mounted(el) {
3    console.log('Element dodany do DOM:', el.tagName)
4  },
5  updated(el) {
6    console.log('Element zaktualizowany:', el.tagName)
7  },
8  unmounted(el) {
9    console.log('Element usunięty:', el.tagName)
10  }
11})

Skrócona forma dyrektywy

Jeżeli potrzebujesz tylko mounted i updated z ta sama logika, możesz użyć skroconej formy - funkcji zamiast obiektu:

1app.directive('color', (el, binding) => {
2  el.style.color = binding.value
3})

To jest równoważne:

1app.directive('color', {
2  mounted(el, binding) {
3    el.style.color = binding.value
4  },
5  updated(el, binding) {
6    el.style.color = binding.value
7  }
8})
Kod do tej lekcji: App.vue
1<script setup>
2import { ref } from 'vue'
3
4// Lokalna dyrektywa v-focus
5const vFocus = {
6  mounted(el) {
7    el.focus()
8  }
9}
10
11// Lokalna dyrektywa v-highlight
12const vHighlight = {
13  mounted(el, binding) {
14    el.style.backgroundColor = binding.value || 'rgba(0, 255, 136, 0.15)'
15    el.style.padding = '4px 8px'
16    el.style.borderRadius = '4px'
17  },
18  updated(el, binding) {
19    el.style.backgroundColor = binding.value || 'rgba(0, 255, 136, 0.15)'
20  }
21}
22
23// Lokalna dyrektywa v-color (skrocona forma)
24const vColor = (el, binding) => {
25  el.style.color = binding.value || '#00ff88'
26}
27
28const searchQuery = ref('')
29const showPanel = ref(true)
30</script>
31
32<template>
33  <div class="nova-lab">
34    <h1>Custom Directives - Podstawy</h1>
35
36    <section class="section">
37      <h2>v-focus - Auto Focus</h2>
38      <input
39        v-focus
40        v-model="searchQuery"
41        placeholder="Wpisz komende stacji..."
42        class="input"
43      />
44      <p class="hint">Ten input dostaje focus automatycznie</p>
45    </section>
46
47    <section class="section">
48      <h2>v-highlight - Podswietlenie</h2>
49      <p v-highlight>Domyslne podswietlenie (zielone)</p>
50      <p v-highlight="'rgba(0, 180, 216, 0.2)'">Podswietlenie cyan</p>
51      <p v-highlight="'rgba(231, 76, 60, 0.2)'">Podswietlenie czerwone</p>
52    </section>
53
54    <section class="section">
55      <h2>v-color - Skrocona forma</h2>
56      <p v-color="'#00ff88'">Tekst zielony</p>
57      <p v-color="'#00b4d8'">Tekst cyan</p>
58      <p v-color="'#e74c3c'">Tekst czerwony</p>
59    </section>
60  </div>
61</template>
62
63<style scoped>
64.nova-lab {
65  background: #0a0e27;
66  color: #c0c0c0;
67  min-height: 100vh;
68  padding: 20px;
69  font-family: monospace;
70}
71h1 { color: #00ff88; margin-bottom: 20px; }
72h2 { color: #00b4d8; font-size: 16px; margin-bottom: 10px; }
73
74.section {
75  background: rgba(0, 180, 216, 0.05);
76  border: 1px solid rgba(0, 180, 216, 0.2);
77  padding: 15px;
78  border-radius: 8px;
79  margin-bottom: 15px;
80}
81
82.input {
83  background: rgba(0, 255, 136, 0.05);
84  border: 1px solid #00ff88;
85  color: #00ff88;
86  padding: 10px 16px;
87  border-radius: 6px;
88  font-family: monospace;
89  font-size: 14px;
90  width: 100%;
91  box-sizing: border-box;
92}
93.input:focus {
94  outline: none;
95  box-shadow: 0 0 8px rgba(0, 255, 136, 0.3);
96}
97.hint {
98  color: #666;
99  font-size: 12px;
100  margin-top: 6px;
101}
102</style>

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Do czego służą Custom Directives w Vue?

  2. 2. Jak zarejestrować dyrektywę globalnie w Vue?

To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.

Zadania praktyczne w grze

  • Edytor kodu

    Zdefiniuj dyrektywę vFocus z hookiem mounted i użyj jej na inpucie.

  • Klikanie w kolejności

    Ułóż hooki Custom Directive w kolejności ich wywoływania:

  • Edytor kodu

    Użyj skróconej formy dyrektywy (funkcja zamiast obiektu) do ustawiania koloru tekstu.

Przydatne artykuły