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

Directive Hooks - argumenty, modyfikatory, wartości

2 min czytania
W tej lekcji6

W Centrum Dowodzenia NOVA LAB każdy system wymaga precyzyjnych parametrów. Dyrektywy Vue oferują bogaty zestaw danych przez obiekt binding.

Obiekt binding

Każdy hook dyrektywy otrzymuje dwa główne parametry: el (element DOM) i binding (obiekt z danymi):

1app.directive('demo', {
2  mounted(el, binding) {
3    // binding.value    - wartość przekazana: v-demo="123" => 123
4    // binding.arg      - argument: v-demo:color => 'color'
5    // binding.modifiers - modyfikatory: v-demo.bold => { bold: true }
6    // binding.oldValue - poprzednia wartość (w updated)
7  }
8})

Wartość dyrektywy: binding.value

Wartość to wyrażenie JavaScript przekazane po =:

1<template>
2  <div v-color="'#00ff88'">Zielony tekst</div>
3  <div v-color="themeColor">Dynamiczny kolor</div>
4  <div v-color="{ bg: '#0a0e27', text: '#00ff88' }">Obiekt</div>
5</template>
1app.directive('color', (el, binding) => {
2  if (typeof binding.value === 'string') {
3    el.style.color = binding.value
4  } else {
5    el.style.backgroundColor = binding.value.bg
6    el.style.color = binding.value.text
7  }
8})

Argumenty: binding.arg

Argument to część po dwukropku - pozwala określić, co dyrektywa ma modyfikować:

1<template>
2  <div v-style:color="'#00ff88'">Kolor tekstu</div>
3  <div v-style:backgroundColor="'#0a0e27'">Kolor tła</div>
4  <div v-style:fontSize="'20px'">Rozmiar czcionki</div>
5</template>
1app.directive('style', (el, binding) => {
2  if (binding.arg) {
3    el.style[binding.arg] = binding.value
4  }
5})

Dynamiczne argumenty

Argument może być dynamiczny - użyj nawiasów kwadratowych:

1<script setup>
2import { ref } from 'vue'
3const prop = ref('color')
4</script>
5
6<template>
7  <div v-style:[prop]="'#00ff88'">Dynamiczny atrybut</div>
8</template>

Modyfikatory: binding.modifiers

Modyfikatory to flagi boolowskie po kropce:

1<template>
2  <p v-format.bold.uppercase>stacja nova lab</p>
3</template>
1app.directive('format', (el, binding) => {
2  if (binding.modifiers.bold) {
3    el.style.fontWeight = 'bold'
4  }
5  if (binding.modifiers.uppercase) {
6    el.textContent = el.textContent.toUpperCase()
7  }
8  if (binding.modifiers.italic) {
9    el.style.fontStyle = 'italic'
10  }
11})

Łączenie wszystkiego razem

Pełna składnia dyrektywy:

1v-nazwa:argument.modyfikator1.modyfikator2="wartosc"

Przykład:

1<div v-tooltip:top.slow="'Informacja o stacji'">
2  Najedz na mnie
3</div>

Gdzie:

  • tooltip - nazwa dyrektywy
  • top - argument (pozycja)
  • slow - modyfikator (animacja)
  • 'Informacja o stacji' - wartość (tekst)
Kod do tej lekcji: App.vue
1<script setup>
2import { ref } from 'vue'
3
4// Dyrektywa z binding.arg
5const vStyle = (el, binding) => {
6  if (binding.arg) {
7    el.style[binding.arg] = binding.value
8  }
9}
10
11// Dyrektywa z binding.modifiers
12const vFormat = (el, binding) => {
13  let text = el.textContent
14  if (binding.modifiers.uppercase) {
15    text = text.toUpperCase()
16  }
17  if (binding.modifiers.lowercase) {
18    text = text.toLowerCase()
19  }
20  el.textContent = text
21  if (binding.modifiers.bold) {
22    el.style.fontWeight = 'bold'
23  }
24  if (binding.modifiers.italic) {
25    el.style.fontStyle = 'italic'
26  }
27}
28
29// Dyrektywa laczaca wszystko
30const vPanel = {
31  mounted(el, binding) {
32    const color = binding.value || '#00ff88'
33    const size = binding.arg || 'md'
34    const paddings = { sm: '8px', md: '16px', lg: '24px' }
35
36    el.style.border = '2px solid ' + color
37    el.style.padding = paddings[size] || paddings.md
38    el.style.borderRadius = '8px'
39
40    if (binding.modifiers.glow) {
41      el.style.boxShadow = '0 0 15px ' + color + '40'
42    }
43    if (binding.modifiers.dashed) {
44      el.style.borderStyle = 'dashed'
45    }
46  }
47}
48
49const dynamicProp = ref('color')
50</script>
51
52<template>
53  <div class="nova-lab">
54    <h1>Directive Hooks - Args & Modifiers</h1>
55
56    <section class="section">
57      <h2>binding.arg (v-style:property)</h2>
58      <p v-style:color="'#00ff88'">Kolor zielony</p>
59      <p v-style:fontSize="'20px'">Wieksza czcionka</p>
60      <p v-style:backgroundColor="'rgba(0, 180, 216, 0.2)'">Tlo cyan</p>
61    </section>
62
63    <section class="section">
64      <h2>binding.modifiers (v-format.bold.uppercase)</h2>
65      <p v-format.uppercase>stacja nova lab</p>
66      <p v-format.bold.italic>wazny komunikat</p>
67      <p v-format.uppercase.bold>alarm czerwony</p>
68    </section>
69
70    <section class="section">
71      <h2>Wszystko razem: v-panel</h2>
72      <div v-panel:md.glow="'#00ff88'" style="margin-bottom: 10px">
73        <p>v-panel:md.glow="#00ff88"</p>
74      </div>
75      <div v-panel:lg.dashed="'#00b4d8'" style="margin-bottom: 10px">
76        <p>v-panel:lg.dashed="#00b4d8"</p>
77      </div>
78      <div v-panel:sm.glow.dashed="'#e74c3c'">
79        <p>v-panel:sm.glow.dashed="#e74c3c"</p>
80      </div>
81    </section>
82
83    <section class="section">
84      <h2>Dynamiczny argument: v-style:[prop]</h2>
85      <select v-model="dynamicProp" class="select">
86        <option value="color">color</option>
87        <option value="fontSize">fontSize</option>
88        <option value="backgroundColor">backgroundColor</option>
89      </select>
90      <p v-style:[dynamicProp]="dynamicProp === 'fontSize' ? '22px' : dynamicProp === 'backgroundColor' ? 'rgba(0,255,136,0.2)' : '#00b4d8'" style="margin-top: 8px">
91        Tekst zmienia sie dynamicznie
92      </p>
93    </section>
94  </div>
95</template>
96
97<style scoped>
98.nova-lab {
99  background: #0a0e27;
100  color: #c0c0c0;
101  min-height: 100vh;
102  padding: 20px;
103  font-family: monospace;
104}
105h1 { color: #00ff88; margin-bottom: 20px; }
106h2 { color: #00b4d8; font-size: 16px; margin-bottom: 10px; }
107.section {
108  background: rgba(0, 180, 216, 0.05);
109  border: 1px solid rgba(0, 180, 216, 0.2);
110  padding: 15px;
111  border-radius: 8px;
112  margin-bottom: 15px;
113}
114.select {
115  background: #0a0e27;
116  color: #00ff88;
117  border: 1px solid #00ff88;
118  padding: 8px;
119  border-radius: 4px;
120  font-family: monospace;
121}
122</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. Co zawiera binding.value w dyrektywie v-demo="123"?

  2. 2. Co zwraca binding.arg w dyrektywie v-style:color="'red'"?

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

Zadania praktyczne w grze

  • Edytor kodu

    Użyj binding.arg jako nazwę właściwości CSS i binding.value jako wartość.

  • Układanie w poziomie

    Ułóż poprawną składnię dyrektywy z argumentem i wartością:

  • Edytor kodu

    Sprawdzaj binding.modifiers.bold, binding.modifiers.uppercase i binding.modifiers.italic.

Przydatne artykuły