Vue Directives
Special attributes that apply reactive behavior to DOM
⚡ What are Vue Directives?
Directives are special attributes with the v- prefix that apply reactive behavior to the DOM. They tell Vue to do something with a DOM element, like show/hide, loop through data, or bind values dynamically.
<!-- v-if directive conditionally renders -->
<p v-if="isVisible">I am visible!</p>
Common Directives
v-if / v-show
Conditional rendering
<p v-if="show">Visible</p>
v-for
Render lists
<li v-for="item in items">
{{ item }}
</li>
v-bind
Bind attributes dynamically
<img :src="imageUrl">
v-on
Listen to events
<button @click="handleClick">
Click
</button>
🔹 v-if, v-else-if, v-else
Conditionally render elements based on conditions:
<template>
<div>
<p v-if="score >= 90">Excellent!</p>
<p v-else-if="score >= 70">Good job!</p>
<p v-else-if="score >= 50">Keep trying!</p>
<p v-else>Need improvement</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const score = ref(85)
</script>
Output (score = 85):
Good job!
🔹 v-show
Toggle element visibility with CSS display property:
<template>
<button @click="isVisible = !isVisible">Toggle</button>
<p v-show="isVisible">Now you see me!</p>
</template>
<script setup>
import { ref } from 'vue'
const isVisible = ref(true)
</script>
v-if vs v-show: v-if removes element from DOM, v-show just hides it with CSS. Use v-show for frequent toggles.
🔹 v-for
Render lists by iterating over arrays or objects:
<template>
<ul>
<li v-for="(fruit, index) in fruits" :key="index">
{{ index + 1 }}. {{ fruit }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const fruits = ref(['Apple', 'Banana', 'Orange'])
</script>
Output:
- 1. Apple
- 2. Banana
- 3. Orange
🔹 v-bind (or :)
Dynamically bind attributes to expressions:
<template>
<img :src="imageUrl" :alt="imageAlt">
<a :href="link">Visit Site</a>
<div :class="{ active: isActive }">Content</div>
<button :disabled="isDisabled">Submit</button>
</template>
<script setup>
import { ref } from 'vue'
const imageUrl = ref('/logo.png')
const imageAlt = ref('Logo')
const link = ref('https://vuejs.org')
const isActive = ref(true)
const isDisabled = ref(false)
</script>
Shorthand:
:src
is shorthand for
v-bind:src
🔹 v-on (or @)
Listen to DOM events and execute JavaScript:
<template>
<button @click="count++">Clicked {{ count }} times</button>
<input @input="handleInput" placeholder="Type here">
<form @submit.prevent="handleSubmit">
<button type="submit">Submit</button>
</form>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
const handleInput = (e) => {
console.log(e.target.value)
}
const handleSubmit = () => {
console.log('Form submitted')
}
</script>
Event Modifiers: .prevent, .stop, .once, .enter, etc.
🔹 v-model
Create two-way data binding on form inputs:
<template>
<input v-model="message" placeholder="Type something">
<p>Message: {{ message }}</p>
<input type="checkbox" v-model="checked">
<p>Checked: {{ checked }}</p>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
const checked = ref(false)
</script>
Result:
Input value automatically syncs with data
🔹 v-text and v-html
Update element's text or HTML content:
<template>
<!-- v-text (same as {{ }} but overwrites content) -->
<p v-text="message"></p>
<!-- v-html (renders HTML, use with caution) -->
<div v-html="htmlContent"></div>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('Hello Vue!')
const htmlContent = ref('<strong>Bold text</strong>')
</script>
Warning: Never use v-html with user-provided content (XSS risk).
🔹 Custom Directives
Create your own directives for reusable DOM manipulation:
// Define custom directive
const vFocus = {
mounted: (el) => el.focus()
}
// Use in template
<input v-focus />