Kurs Vue.js · Moduł 14: Dyrektywy i pluginy
Custom Directives - Podstawy
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 elementubeforeMount- przed wstawieniem elementu do DOMmounted- element jest już w DOM (najczęściej używany)beforeUpdate- przed aktualizacją komponentu rodzicaupdated- po aktualizacji komponentu rodzicabeforeUnmount- przed usunięciem z DOMunmounted- 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. Do czego służą Custom Directives w Vue?
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.