Avoid extra divs using the template tag in VueJS

  • Written on: Th Jun 2019
  • Last update: Th Jun 2019

I discovered a while ago a very simple way to avoid having extra div tags in our markups.

Very often with Vue, we use v-if to show / hide some elements according to a specific condition. And in some cases, we want to apply the same condition to many elements like:

<template>
  <div id="app">
    <div v-if="myCondition">
      My thing
    </div>
    <div v-if="myCondition">
      My other thing
    </div>
  </div>
</template>

In that case, it would be good if we can avoid duplicating the condition two times. To deal with that, we sometimes add an extra <div> tag that wraps both elements.

<template>
  <div id="app">
    <div v-if="myCondition">
      <div>
        My thing
      </div>
      <div>
        My other thing
      </div>
    </div>
  </div>
</template>

That will works perfectly fine but It comes with two major issues:

  • you added an extra DOM level, for not much
  • you may break your styling by adding that extra div, specially if you're working with flexboxes; you may end up adding the same styling from the parent div, to the extra div.

But hey! There is a solution for that. Vue comes with a special tag that we see everyday but for some of use, don't really know what is it's purpose. I'm talking about that <template> tag.

To make it simple, the template tag says "take what's inside myself and replace it, in the dom, in my spot". If we apply to our example:

<template>
  <div id="app">
    <template v-if="myCondition">
      <div>
        My thing
      </div>
      <div>
        My other thing
      </div>
    </template>
  </div>
</template>

This will take the two divs nested in the template tag, and render them, where the template tag is located. That means it will render:

<div id="app">
  <div>
    My thing
  </div>
  <div>
    My other thing
  </div>
</div>

instead of

<div id="app">
  <div>
    <div>
      My thing
    </div>
    <div>
      My other thing
    </div>
  </div>
</div>

with the extra div method.