DEV Community

Valerie Foster
Valerie Foster

Posted on

Getting Started With Vue.js: Directives

Continuing on from my last two blog posts, I’ll be talking more about some of the basics of Vue.js. I have covered how to start a project using Vue and some of the ways you can use the Vue instance in a project. In this post, I’ll go over Vue’s directives; the way to make your webpages interactive with the data in your Vue instances.

Directives are special attributes provided by Vue. They are prefixed with v- and each one applies specific reactive behavior to the HTML element you add it to on the page. The main Vue directives are v-bind, v-if, v-for, and v-on. An example using v-bind looks like this:

<div v-bind:id="someVariable"></div>
Enter fullscreen mode Exit fullscreen mode

The v-bind attribute is used to access Vue instance variables from inside an HTML attribute. The example above shows the v-bind attribute being used to assign the id of the div to a variable called someVariable. Unlike referencing a variable in between HTML elements, you cannot use double curly braces to interpret variables in HTML attributes, you have to use v-bind instead:

<!-- Doesn't work, causes an error! -->
<a href={{ url }}>Vue.js</a>
<!-- This is the correct way to assign the href attribute to url -->
<a v-bind:href="url">Vue.js</a>
Enter fullscreen mode Exit fullscreen mode

You can use v-bind to assign any attribute an element might have to a variable. But v-bind can get more confusing when you need to attach more than one variable to an attribute. When adding styling to a page, the class and style attributes might need to have many variables associated with them. In that case, you can use array or object syntax with v-bind, like these examples with multiple classes on each element:

<div v-bind:class="[activeClass, errorClass]">
  <!-- This will have the class names of whatever is in
    the 'activeClass' and 'errorClass' variables -->
</div>
<div v-bind:class="{ active: isActive, 'text-danger': hasError }" >
  <!-- This will have the classes of 'active' and 'text-danger'
    depending on if their variables are true or false -->
</div>
Enter fullscreen mode Exit fullscreen mode

When using the style attribute, it’s often better to create a style object in the instance to bind to the attribute:

// in index.html
<div v-bind:style="styleObject">
  <!-- content -->
</div>
// in index.js
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}
Enter fullscreen mode Exit fullscreen mode

This way, if your style object gets too big, it’s not taking up space in your HTML.

The next directive uses a concept that should be very familiar to any programmer. The v-if directive is used for conditional rendering, and it evaluates the condition it is given the same way as an if-statement does in code. For example:

<div id="if-directive">
  <h1 v-if="condition">I'm conditionally rendered!</h1>
</div>
Enter fullscreen mode Exit fullscreen mode

In this example, the condition that v-if points to should be some data that you have defined that can be evaluated to true or false. Now, if the condition is true, you will see the h1 tag on the webpage, and if it is false, this will be an empty div. You can test this out by creating a Vue instance attached to this div:

let ifDirective = new Vue({
  el: "#if-directive",
  data: {
    condition: true
  }
})
Enter fullscreen mode Exit fullscreen mode

Now, if you have the page open in your browser, you should see the h1 tag, but if you open the console and set ifDirective.condition to false, you can see the header disappear.

Just like if-statements with any programming language, v-if also has the associated v-else and v-else-if so you can give other options for what to render depending on a variety if conditions, like this:

<div id="gender">
  <p v-if="person.gender === 'M'">
    Male
  </p>
  <p v-else-if="person.gender === 'F'">
    Female
  </p>
  <p v-else>
    Other
  </p>
</div>
Enter fullscreen mode Exit fullscreen mode

And the last directive I’ll talk about in this post is v-for. This should also sound familiar to any programmer, and as you might expect, the v-for attribute is designed to loop over a collection or list. Here’s an example of what a Vue instance with a list could look like:

const forDirective = new Vue({
  el: "#for-directive",
  data: {
    todos: [
      { text: 'Wash dishes', isComplete: false },
      { text: 'Do laundry', isComplete: true },
      { text: 'Check email', isComplete: false }
    ]
  }
})
Enter fullscreen mode Exit fullscreen mode

And the HTML would look like this:

<ul id="for-directive">
  <li v-for="todo in todos">
    {{ todo.text }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Todo List This will render a list like the one above. If you have the index.html page open in your browser and you open the console, you can add or remove items in the todos array and see the list update on the page. The list will always update whenever there is a change to the list in your instance. The v-for attribute also gives you the ability to loop over an object, and a way to access the index and/or key of each of the elements in the collection:

// Using the index of each item in the array
v-for="(item, index) in items"
// Looping over an object
v-for="value in object"
// Looping over an object with it's key names and index values
v-for="(value, name, index) in object"
Enter fullscreen mode Exit fullscreen mode

One thing to note is that it is not advised to use v-if with v-for. The main reason to try to use them together is when you only want to display items in the list that fit a condition. But the better way to do this is to use a computed property. You should use computed properties to display a sorted or filtered part of your original list. If we use the example from earlier with the todo list, we could add a computed property to the instance that filters the list by items that are not completed, like so:

computed: {
  completedTodos: function () {
    return this.todos.filter(function (todo) {
      return !todo.isComplete
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

Then you can use v-for with this computed property to only display the todos that are not completed to the page:

<li v-for="todo in completedTodos">
  {{ todo.text }}
</li>
Enter fullscreen mode Exit fullscreen mode

Another thing to note about the v-for directive is that you should give each element in the list a unique key attribute. This is so that Vue can properly keep track of each element’s identity so it will reuse existing elements, instead of recreating them when there is a change to the collection:

<div v-for="item in items" v-bind:key="item.id">
  <!-- content -->
</div>
Enter fullscreen mode Exit fullscreen mode

Now, with everything I have talked about in my blog posts on Vue, I have covered most of the different ways to display data from your Vue instances to a webpage. And because of the the way Vue is set up, the page will change according to any updates that are made to the data. But I still haven’t really covered how to allow a user to interact with your webpage. That requires the use of the v-on directive, and I’ll spend time talking about that in my next blog post.

Top comments (0)