Directives

A directive is a special HTML attribute, prefixed with v-, that tells Vue to do something extra to an element — show it conditionally, repeat it for each item in a list, or bind it to data.

v-if: only render when a condition is true

v-if removes the element from the page entirely when its expression is false — not just hidden with CSS, genuinely absent from the DOM:

HTML template
<p v-if="isLoggedIn">Welcome back!</p>
<p v-else>Please log in.</p>
Rendered, with isLoggedIn: false
<p>Please log in.</p>

v-show: hide with CSS instead

v-show looks similar but works differently — the element always stays in the DOM, and Vue just toggles display: none on it:

HTML template
<p v-show="isLoggedIn">Welcome back!</p>
Rendered, with isLoggedIn: false
<p style="display: none;">Welcome back!</p>

Because v-show never removes the element, toggling it is cheaper than v-if — but the element (and anything inside it) still exists and still gets initialized. Use v-show for something that flips on and off frequently, and v-if for something that's rarely shown at all or genuinely shouldn't exist in the DOM when hidden.

v-for: repeat an element per item

v-for loops over an array (or object) and renders the element once per entry:

HTML template
<ul>
  <li v-for="item in groceries" :key="item.id">
    {{ item.name }}
  </li>
</ul>
Rendered, with groceries: [{id:1,name:'Milk'},{id:2,name:'Eggs'}]
<ul>
  <li>Milk</li>
  <li>Eggs</li>
</ul>
Always add :key with v-for: the :key binding gives Vue a stable identity for each rendered item, so when the list changes it can figure out which items moved, were added, or were removed, instead of blindly re-rendering everything in place. Skipping :key (or using the array index as the key on a list that gets reordered) is one of the most common sources of subtle rendering bugs in Vue apps — items appearing to keep stale input values or animations after a reorder.