Vue.js course Β· Module 14: Directives & Plugins

Directive Hooks - Arguments, Modifiers, Values

2 min read
In this lesson6

In the NOVA LAB Command Center, every system requires precise parameters. Vue directives offer a rich set of data through the binding object.

The Binding Object

Each directive hook receives two main parameters: el (the DOM element) and binding (an object with data):

1app.directive('demo', {
2  mounted(el, binding) {
3    // binding.value    - the passed value: v-demo="123" => 123
4    // binding.arg      - the argument: v-demo:color => 'color'
5    // binding.modifiers - modifiers: v-demo.bold => { bold: true }
6    // binding.oldValue - the previous value (in updated)
7  }
8})

Directive Value: binding.value

The value is the JavaScript expression passed after =:

1<template>
2  <div v-color="'#00ff88'">Green text</div>
3  <div v-color="themeColor">Dynamic color</div>
4  <div v-color="{ bg: '#0a0e27', text: '#00ff88' }">Object</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})

Arguments: binding.arg

The argument is the part after the colon - it lets you specify what the directive should modify:

1<template>
2  <div v-style:color="'#00ff88'">Text color</div>
3  <div v-style:backgroundColor="'#0a0e27'">Background color</div>
4  <div v-style:fontSize="'20px'">Font size</div>
5</template>
1app.directive('style', (el, binding) => {
2  if (binding.arg) {
3    el.style[binding.arg] = binding.value
4  }
5})

Dynamic Arguments

The argument can be dynamic - use square brackets:

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

Modifiers: binding.modifiers

Modifiers are boolean flags after a dot:

1<template>
2  <p v-format.bold.uppercase>nova lab station</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})

Putting It All Together

Full directive syntax:

1v-name:argument.modifier1.modifier2="value"

Example:

1<div v-tooltip:top.slow="'Station information'">
2  Hover over me
3</div>

Where:

  • tooltip - directive name
  • top - argument (position)
  • slow - modifier (animation)
  • 'Station information' - value (text)
Code for this lesson: App.vue
1<script setup>
2import { ref } from 'vue'
3
4// Directive with binding.arg
5const vStyle = (el, binding) => {
6  if (binding.arg) {
7    el.style[binding.arg] = binding.value
8  }
9}
10
11// Directive with 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// Directive combining everything
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'">Green color</p>
59      <p v-style:fontSize="'20px'">Larger font</p>
60      <p v-style:backgroundColor="'rgba(0, 180, 216, 0.2)'">Cyan background</p>
61    </section>
62
63    <section class="section">
64      <h2>binding.modifiers (v-format.bold.uppercase)</h2>
65      <p v-format.uppercase>nova lab station</p>
66      <p v-format.bold.italic>important message</p>
67      <p v-format.uppercase.bold>red alert</p>
68    </section>
69
70    <section class="section">
71      <h2>All together: 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>Dynamic 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        Text changes dynamically
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>

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. What does binding.value contain in the directive v-demo="123"?

  2. 2. What does binding.arg return in the directive v-style:color="'red'"?

These are 2 of 3 questions for this lesson. Solve the rest in the game.

Hands-on tasks in the game

  • Code editor

    Use binding.arg as the CSS property name and binding.value as the value.

  • Horizontal ordering

    Arrange the correct syntax of a directive with an argument and value:

  • Code editor

    Check binding.modifiers.bold, binding.modifiers.uppercase, and binding.modifiers.italic.

Useful articles