Different Vue Directives
Vue directives are special HTML attributes with the prefix v-
that give the HTML tag extra functionality. Vue directives connect to the Vue instance to create dynamic and reactive user interfaces.
With Vue, creating responsive pages is much easier and requires less code compared to traditional JavaScript methods.
Different Vue Directives
The different Vue directives we use in this tutorial are listed below.
Directive | Details |
v-bind |
Creates HTML tags depending on a condition. Directives v-else-if and v-else are used together with the v-if directive. |
v-if | Creates HTML tags depending on a condition. Directives v-else-if and v-else are used together with the v-if directive.v-show |
v-show | Specifies if an HTML element should be visible or not depending on a condition. |
v-for | Creates a list of tags based on an array in the Vue instance using a for-loop. |
v-on | Connects an event on an HTML tag to a JavaScript expression or a Vue instance method. We can also define more specifically how our page should react to a certain event by using event-modifiers |
v-model | Used in HTML forms with tags like <form> , <input> and <button> . Creates a two way binding between an input element and a Vue instance data property. |
Vue v-bind
Directive
The v-bind
directive lets us bind an HTML attribute to data in the Vue instance. This makes it easy to change the attribute value dynamically.
<div v-bind:[attribute]="[Vue data]"></div>
Example
The src
attribute value of an <img>
tag is taken from the Vue instance data property ‘url’:
<img v-bind:src="url">
CSS Binding
We can use the v-bind
directive to do in-line styling and modify classes dynamically. We will show you briefly how to do that in this section.
Bind style
In-line styling with Vue is done by binding the style attribute to Vue with v-bind
.
As a value to the v-bind directive, we can write a JavaScript object with the CSS property and value:
Example
The font size depends on the Vue data property ‘size’.
<div v-bind:style="{ fontSize: size }">
Text example
</div>
An example of this:
<!DOCTYPE html>
<html>
<head>
<title>v-bind font-size</title>
<style>
#app > div {
width: 200px;
padding: 20px;
border: dashed black 1px;
background-color: lightcoral;
}
</style>
</head>
<body>
<h1>'v-bind' Font Size Example</h1>
<p>The browser sets the font-size based on the value of 'size' in the Vue instance.</p>
<div id="app">
<div v-bind:style="{ fontSize: size }">Text example</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
size: '28px'
}
}
})
app.mount('#app')
</script>
</body>
</html>
If you run this it can show you the following:
'v-bind' Font Size Example
The browser sets the font-size based on the value of 'size' in the Vue instance.
Text example
The CSS property fontSize is referred to as ‘font-size’.
<div v-bind:style="{ 'font-size': size + 'px' }">
Text example
</div>
The background color depends on the ‘bgVal’ data property value inside the Vue instance.
<div v-bind:style="{ backgroundColor: 'hsl('+bgVal+',80%,80%)' }">
Notice the background color on this div tag.
</div>
The background color is set with a JavaScript conditional (ternary) expression depending on whether the ‘isImportant’ data property value is ‘true’ or ‘false’.
<div v-bind:style="{ backgroundColor: isImportant ? 'lightcoral' : 'lightgray' }">
Conditional background color
</div>
Bind class
We can use v-bind
to change the class attribute.
The value of v-bind:class
can be a variable:
Example
The class
name is taken from the ‘className’ Vue data property:
<div v-bind:class="className">
The class is set with Vue
</div>
When the value of v-bind:class
is an object, the class can be assigned depending on a Vue property:
Example
The class
attribute is assigned depending on the ‘isImportant’ property, if it is ‘true’ or ‘false’:
<div v-bind:class="{ myClass: isImportant }">
The class is set conditionally to change the background color
</div>
Shorthand for v-bind
The shorthand for ‘v-bind:
‘ is simply ‘:
‘.
Example
Here we just write ‘:
‘ instead of ‘v-bind:
‘:
<div :class="{ impClass: isImportant }">
The class is set conditionally to change the background color
</div>
Vue v-if
Directive
It is a lot easier to create an HTML element depending on a condition in Vue with the v-if
directive than with plain JavaScript.
With Vue you just write the if-statement directly in the HTML element you want to create conditionally. It’s that simple.
Conditional Rendering in Vue
Conditional rendering in Vue is done by using the v-if
, v-else-if
and v-else
directives.
Conditional rendering is when an HTML element is created only if a condition is true, i.e. create the text “In stock” if a variable is ‘true’, or ‘Not in stock’ if that variable is ‘false’.
Example
Write different messages depending on whether there are any typewriters in stock or not:
<p v-if="typewritersInStock">
in stock
</p>
<p v-else>
not in stock
</p>
Conditions in Vue
A condition, or “if-statement”, is something that is either true
or false
.
A condition is often a comparison check between two values like in the example above to see if one value is greater than the other.
- We use comparison operators like
<
,>=
or!==
to do such checks. - Comparison checks can also be combined with logical operators such as
&&
or||
.
We can use the number of typewriters in storage with a comparison check to decide if they are in stock or not:
Example
Use a comparison check to decide whether to write “In stock” or “Not in stock” depending on the number of typewriters in storage.
<p v-if="typewriterCount > 0">
in stock
</p>
<p v-else>
not in stock
</p>
Directives for Conditional Rendering
This overview describes how the different Vue directives used for conditional rendering are used together.
Directive | Details |
---|---|
v-if |
Can be used alone, or with v-else-if and/or v-else . If the condition inside v-if is ‘true’, v-else-if or v-else are not considered. |
v-else-if |
Must be used after v-if or another v-else-if . If the condition inside v-else-if is ‘true’, v-else-if or v-else that comes after are not considered. |
v-else |
This part will happen if the first part of the if-statement is false. Must be placed at the very end of the if-statement, after v-if |
To see an example with all three directives shown above, we can expand the previous example with v-else-if
so that the user sees ‘In stock’, ‘Very few left!’ or ‘Out of stock’:
Example
Use a comparison check to decide whether to write “In stock”, “Very few left!” or “Not in stock” depending on the number of typewriters in storage.
<p v-if="typewriterCount>3">
In stock
</p>
<p v-else-if="typewriterCount>0">
Very few left!
</p>
<p v-else>
Not in stock
</p>
Use The Return Value from a Function
Instead of using a comparison check with the v-if
directive, we can use the ‘true’ or ‘false’ return value from a function:
Example
If a certain text contains the word ‘pizza’, create a <p> tag with an appropriate message. The ‘includes()’ method is a native JavaScript method that checks if a text contain certain words.
<div id="app">
<p v-if="text.includes('pizza')">The text includes the word 'pizza'</p>
<p v-else>The word 'pizza' is not found in the text</p>
</div>
data() {
return {
text: 'I like taco, pizza, Thai beef salad, pho soup and tagine.'
}
}
The example above can be expanded to show that v-if
also can create other tags like <div> and <img> tags:
Example
If a certain text contains the word ‘pizza’, create a <div> tag with a pizza image and a <p> tag with a message. The ‘includes()’ method is a native JavaScript method that check if a text contain certain words.
<div id="app">
<div v-if="text.includes('pizza')">
<p>The text includes the word 'pizza'</p>
<img src="img_pizza.svg">
</div>
<p v-else>The word 'pizza' is not found in the text</p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
text: 'I like taco, pizza, Thai beef salad, pho soup and tagine.'
}
}
})
app.mount('#app')
</script>
Below the example is expanded even more.
Example
If a certain text contains the word ‘pizza’ or ‘burrito’ or none of these words, different images and texts will be created.
<div id="app">
<div v-if="text.includes('pizza')">
<p>The text includes the word 'pizza'</p>
<img src="img_pizza.svg">
</div>
<div v-else-if="text.includes('burrito')">
<p>The text includes the word 'burrito', but not 'pizza'</p>
<img src="img_burrito.svg">
</div>
<p v-else>The words 'pizza' or 'burrito' are not found in the text</p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
text: 'I like taco, pizza, Thai beef salad, pho soup and tagine.'
}
}
})
app.mount('#app')
</script>
Vue v-show
Directive
v-show
is easy to use because the condition is written right in the HTML tag attribute.
Conditional Visibility
The v-show
directive hides an element when the condition is ‘false’ by setting the CSS ‘display’ property value to ‘none’.
After writing v-show
as an HTML attribute we must give a condition to decide to have the tag visible or not.
<div v-show="showDiv">This div tag can be hidden</div>
In the code above, ‘showDiv’ represents a boolean Vue data property with either ‘true’ or ‘false’ as property value. If ‘showDiv’ is ‘true’ the div tag is shown, and if it is ‘false’ the tag is not shown.
Example
Display the <div> element only if the showDiv property is set to ‘true’.
<div id="app">
<div v-show="showDiv">This div tag can be hidden</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
showDiv: true
}
}
})
app.mount('#app')
</script>
v-show
vs. v-if
The difference between v-show
and v-if
is that v-if
creates (renders) the element depending on the condition, but with v-show
the element is already created, v-show
only changes its visibility.
Therefore, it is better to use v-show
when switching visibility of an object, because it is easier for the browser to do, and it can lead to a faster response and better user experience.
A reason for using v-if
over v-show
is that v-if
can be used with v-else-if
and v-else
.
In the example below v-show
and v-if
are used separately on two different <div> elements, but based on the same Vue property. You can open the example and inspect the code to see that v-show
keeps the <div> element, and only sets the CSS display property to ‘none’, but v-if
actually destroys the <div> element.
Example
Display the two <div> elements only if the showDiv property is set to ‘true’. If the showDiv property is set to ‘false’ and we inspect the example page with the browser we can see that the <div> element with v-if
is destroyed, but the <div> element with v-show
has just CSS display property set to ‘none’.
<div id="app">
<div v-show="showDiv">Div tag with v-show</div>
<div v-if="showDiv">Div tag with v-if</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
showDiv: true
}
}
})
app.mount('#app')
</script>
Vue v-for
Directive
With normal JavaScript you might want to create HTML elements based on an array. You use a for-loop, and inside you need to create the elements, adjust them, and then add each element to your page. And these elements will not react to a change in the array.
With Vue you start with the HTML element you want to create into a list, with v-for
as an attribute, refer to the array inside the Vue instance, and let Vue take care of the rest. And the elements created with v-for
will automatically update when the array changes.
List Rendering
List rendering in Vue is done by using the v-for
directive, so that several HTML elements are created with a for-loop.
Below are three slightly different examples where v-for
is used.
Example
Display a list based on the items of an array.
<ol>
<li v-for="x in manyFoods">{{ x }}</li>
</ol>
Loop Through an Array
Loop through an array to display different images:
Example
Show images of food, based on an array in the Vue instance.
<div>
<img v-for="x in manyFoods" v-bind:src="x">
</div>
Loop Through Array of Objects
Loop through an array of objects and display the object properties:
Example
Show both images and names of different types of food, based on an array in the Vue instance.
<div>
<figure v-for="x in manyFoods">
<img v-bind:src="x.url">
<figcaption>{{ x.name }}</figcaption>
</figure>
</div>
Get the index
The index number of an array element can be really useful in JavaScript for-loops. Luckily we can get the index number when using v-for
in Vue as well.
To get the index number with v-for
we need to give two comma separated words in parentheses: the first word will be the array element, and the second word will be the index of that array element.
Example
Show index number and food name of elements in the ‘manyFoods’ array in the Vue instance.
<p v-for="(x, index) in manyFoods">
{{ index }}: "{{ x }}" <br>
</p>
We can also display both array element index and information from the array element itself, if the array elements are objects:
Example
Show both the array element index number, and text from the objects in the ‘manyFoods’ array.
<p v-for="(x, index) in manyFoods">
{{ index }}: "{{ x.name }}", url: "{{ x.url }}" <br>
</p>
Vue Events
Event handling in Vue is done with the v-on
directive, so that we can make something happen when for example a button is clicked.
Event handling is when HTML elements are set up to run a certain code when a certain event happens.
Events in Vue are easy to use and will make our page truly responsive.
Vue methods are code that can be set up to run when an event happens.
With v-on
modifiers you can describe in more detail how to react to an event.
Get started with events
Lets start with an example to show how we can click a button to count moose in a forest.
We need:
- A button
v-on
on the <button> tag to listen to the ‘click’ event- Code to increase the number of moose
- A property (variable) in the Vue instance to hold the number of moose
- Double curly braces
{{}}
to show the increased number of moose
Example
Click the button to count one more moose in the forest. The count property increases each time the button is clicked.
<div id="app">
<img src="img_moose.jpg">
<p>{{ "Moose count: " + count }}</p>
<button v-on:click="count++">Count moose</button>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
}
})
app.mount('#app')
</script>
Note: A benefit that comes with Vue is that the number of moose in the <p> tag is updated automatically. With plain JavaScript we would need to update the number the user sees with an additional line of code.
Events
There are lots of events we can use as triggers for running code, among the most common ones are: ‘click’, ‘mouseover’, ‘mouseout’, ‘keydown’ and ‘input’.
‘v-on’
The v-on
directive allows us to create pages that respond to what the user does.
The Vue v-on
works by telling the browser what event to listen to, and what to do when that event occurs.
Methods
If we want to run more complex code when an event occurs we can put the code in a Vue method and refer to this method from the HTML attribute, like this:
<p v-on:click="changeColor">Click me</p>
Event Modifiers
In addition to v-on
and Vue methods we can use something called event modifiers to modify an event so that it for example only happens once after a page is loaded, or modify an event like ‘submit’ to prevent a form from being submitted.
Learn More
As we can see, there are three techniques we need to learn about to use events in Vue:
- The Vue
v-on
directive - Vue methods
- Vue
v-on
modifiers
Vue v-on
Directive
Like event handling in plain JavaScript, the v-on
directive in Vue tells the browser:
- which event to listen to (‘click’, ‘keydown’, ‘mouseover’, etc)
- what to do when that event occurs
Examples using v-on
Let’s take a look at some examples to see how v-on
can be used with different events and different code to run when these events occur.
onclick Event
The v-on directive allows us to perform actions based on specified events.
Use v-on:click
to perform action when the element is clicked.
Example
The v-on
directive is used on the <button> tag to listen to the ‘click’ event. When the ‘click’ event occurs the ‘lightOn’ data property is toggled between ‘true’ and ‘false’, making the yellow <div> behind the lightbulb visible/hidden.
<div id="app">
<div id="lightDiv">
<div v-show="lightOn"></div>
<img src="img_lightBulb.svg">
</div>
<button v-on:click="lightOn = !lightOn">Switch light</button>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
lightOn: false
}
}
})
app.mount('#app')
</script>
oninput Event
Use v-on:input
to perform action when the element gets an input, like a keystroke inside a text field.
Example
Count the number of keystroke for a input text field:
div id="app">
<input v-on:input="inpCount++">
<p>{{ 'Input events occured: ' + inpCount }}</p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
inpCount: 0
}
}
})
app.mount('#app')
</script>
mousemove Event
Use v-on:mousemove
to perform action when the mouse pointer moves over an element.
Example
Change the background color of a <div> element whenever the mouse pointer moves over it:
<div id="app">
<p>Move the mouse pointer over the box below</p>
<div v-on:mousemove="colorVal=Math.floor(Math.random()*360)"
v-bind:style="{backgroundColor:'hsl('+colorVal+',80%,80%)'}">
</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
colorVal: 50
}
}
})
app.mount('#app')
</script>
Use v-on in a v-for Loop
You can also use the v-on
directive inside a v-for
loop.
The items of the array are available for each iteration inside the v-on
value.
Example
Display a list based on the food array and add an click event for each item that will use a value from the array item to change the source of an image.
<div id="app">
<img v-bind:src="imgUrl">
<ol>
<li v-for="food in manyFoods" v-on:click="imgUrl=food.url">
{{ food.name }}
</li>
</ol>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
imgUrl: 'img_salad.svg',
manyFoods: [
{name: 'Burrito', url: 'img_burrito.svg'},
{name: 'Salad', url: 'img_salad.svg'},
{name: 'Cake', url: 'img_cake.svg'},
{name: 'Soup', url: 'img_soup.svg'}
]
}
}
})
app.mount('#app')
</script>
Shorthand for v-on
The shorthand for ‘v-on
‘ is simply ‘@
‘.
Example
Here we just write ‘@
‘ instead of ‘v-on
‘:
<button @:click="lightOn = !lightOn">Switch light</button>
Vue v-model
Directive
Compared to normal JavaScript, it is easier to work with forms in Vue because the v-model
directive connects with all types of input elements in the same way.
v-model
creates a link between the input element value
attribute and a data value in the Vue instance. When you change the input, the data updates and when the data changes, the input updates as well (two-way binding).
Two-way Binding
The example below also demonstrates the two-way binding with v-model
.
Example
Two-way binding: Try to write inside the input field to see that the Vue data property value gets updated. Try also to write directly in the code to change the Vue data property value, run the code, and see how the input field is updated.
<div id="app">
<input type="text" v-model="inpText">
<p> {{ inpText }} </p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
inpText: 'Initial text'
}
}
})
app.mount('#app')
</script>
Note: The v-model
two-way binding functionality could actually be achieved with a combination of v-bind:value
and v-on:input
:
v-bind:value
to update the input element from the Vue instance data,- and
v-on:input
to update the Vue instance data from the input.
But v-model
is much easier to use so that is what we will do.
A Dynamic Checkbox
We add a checkbox to our shopping list on the previous page to mark if an item is important or not.
Next to the checkbox we add a text that allways reflects the current ‘important’ status, changing dynamically between ‘true’ or ‘false’.
We use v-model
to add this dynamic checkbox and text to improve user interaction.
We need:
- a boolean value in the Vue instance data property called ‘important’
- a checkbox where the user can check if the item is important
- a dynamic feedback text so that the user can see if the item is important
Below is how the ‘important’ feature looks, isolated from the shopping list.
Example
The checkbox text is made dynamic so that the text reflects the current checkbox input value.
<div id="app">
<form>
<p>
Important item?
<label>
<input type="checkbox" v-model="important">
{{ important }}
</label>
</p>
</form>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
important: false
}
}
})
app.mount('#app')
</script>
Let’s include this dynamic feature in our shopping list example.
<div id="app">
<form v-on:submit.prevent="addItem">
<p>Add item</p>
<p>Item name: <input type="text" required v-model="itemName"></p>
<p>How many: <input type="number" v-model="itemNumber"></p>
<p>
Important?
<label>
<input type="checkbox" v-model="itemImportant">
{{ important }}
</label>
</p>
<button type="submit">Add item</button>
</form>
<hr>
<p>Shopping list:</p>
<ul>
<li v-for="item in shoppingList">{{item.name}}, {{item.number}}</li>
</ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
itemName: null,
itemNumber: null,
important: false,
shoppingList: [
{ name: 'Tomatoes', number: 5, important: false }
]
}
},
methods: {
addItem() {
let item = {
name: this.itemName,
number: this.itemNumber
important: this.itemImportant
}
this.shoppingList.push(item)
this.itemName = null
this.itemNumber = null
this.itemImportant = false
}
}
})
app.mount('#app')
</script>
Mark Found Items in The Shopping List
Let’s add functionality so that items added to the shopping list can be marked as found.
We need:
- the list items to react on click
- to change the status of the clicked item to ‘found’, and use this to visually move the item away and strike it through with CSS
We create one list with all items we need to find, and one list below with items found striked through. We can actually put all the items in the first list, and all the items in the second list, and just use v-show
with the Vue data property ‘found’ to define whether to show the item in the first or second list.
Example
After adding items to the shopping list we can pretend to go shopping, clicking the items away after finding them. If we click an item by mistake we can take it back to the ‘not found’ list by clicking the item once more.
<div id="app">
<form v-on:submit.prevent="addItem">
<p>Add item</p>
<p>Item name: <input type="text" required v-model="itemName"></p>
<p>How many: <input type="number" v-model="itemNumber"></p>
<p>
Important?
<label>
<input type="checkbox" v-model="itemImportant">
{{ important }}
</label>
</p>
<button type="submit">Add item</button>
</form>
<p><strong>Shopping list:</strong></p>
<ul id="ulToFind">
<li v-for="item in shoppingList"
v-bind:class="{ impClass: item.important }"
v-on:click="item.found=!item.found"
v-show="!item.found">
{{ item.name }}, {{ item.number}}
</li>
</ul>
<ul id="ulFound">
<li v-for="item in shoppingList"
v-bind:class="{ impClass: item.important }"
v-on:click="item.found=!item.found"
v-show="item.found">
{{ item.name }}, {{ item.number}}
</li>
</ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
itemName: null,
itemNumber: null,
important: false,
shoppingList: [
{ name: 'Tomatoes', number: 5, important: false, found: false }
]
}
},
methods: {
addItem() {
let item = {
name: this.itemName,
number: this.itemNumber,
important: this.itemImportant,
found: false
}
this.shoppingList.push(item)
this.itemName = null
this.itemNumber = null
this.itemImportant = false
}
}
})
app.mount('#app')
</script>
Use v-model to make The Form Itself Dynamic
We can make a form where the customer orders from a menu. To make it easy for the customer, we only present the drinks to choose from after the customer chooses to order drinks. This is can be argued to be better than presenting the customer with all items from the menu at once. In this example we use v-model
and v-show
to make the form itself dynamic.
We need:
- A form, with relevant input tags and ‘Order’ button.
- Radio-buttons to select ‘Dinner’, ‘Drink’ or ‘Dessert’.
- After category is chosen, a dropdown menu appears with all the items in that category.
- When an item is chosen you see an image of it, you can choose how many and add it to the order. The form is reset when the item is added to the order.
Conclusion
In this post we have explored Different Vue Directives: v-bind, v-if, v-show, v-for, v-on, v-model and their syntax, examples how to use.
This post is part of Vue-Step by step.
Useful links to learn completely Vue, Look to the following links:
vuejs.org