Una de las ventajas de la sección <template> de los componentes SFC de Vue es que no sólo puedes escribir HTML clásico, sino que además también tienes una sintaxis avanzada para realizar algunas características interesantes que lo hacen mucho más potente que el HTML puro, como por ejemplo, el uso de directivas.

Directivas de Vue

Las directivas de Vue son atributos especiales que se colocan en las etiquetas HTML y están prefijados por v-, como por ejemplo, v-for, v-bind o v-on, entre muchas otras. Estas directivas permiten realizar acciones dinámicas potentes (bucles, condicionales, etc...) que no se pueden realizar en HTML por si solo, pero que Vue permite utilizar en sus etiquetas <template>.

Directivas de Vue

Dichas directivas están formadas por varias partes:

  • Directiva: El nombre de la directiva, que a veces, es posible abreviarlo con un carácter.
  • Argumento: En ciertas directivas se indica un parámetro.
  • Modificador: En ciertas directivas se puede modificar el comportamiento.
  • Valor: En ciertas directivas, se requiere establecer un valor. Se escribe como el valor de un atributo HTML.

Existen varias directivas en Vue, las he dividido en varios grupos e iremos profundizando en ellas a lo largo de los siguientes capítulos y temas:

Tipos de directivas Ejemplos Descripción
Directivas básicas v-pre, v-once, v-model... Permite realizar tareas simples.
Directivas condicionales v-show, v-if, v-else... Permiten realizar acciones según condiciones.
Directivas de bucles v-for Permiten realizar operaciones varias veces.
Directivas avanzadas v-bind, v-on, v-slot Permiten realizar tareas más específicas.
Directivas personalizadas Directivas propias definidas por el usuario.

Empezaremos por las directivas básicas, ya que son las más sencillas de comprender y continuaremos con el resto a lo largo de los siguientes temas. Observa que en este primer bloque de directivas, no todas requieren aplicar un valor:

Directiva vue Valor Descripción
v-text Equivalente a {{ texto }}. Usa .textContent internamente.
v-html Inserta HTML en un elemento sin procesarlo. Usa .innerHTML internamente.
v-pre No Mantiene las {{ templates }} del elemento intactas, sin renderizar.
v-once No Renderiza las {{ templates }} solo la primera vez, y no lo hace más.
v-cloak No Directiva que permanece hasta que la {{ template }} se renderiza con contenido.
v-model Enlaza el valor de una variable con un <input>, <select>, <textarea> o un componente.

En la práctica, recuerda que en nuestros componentes de Vue existirá una parte visual que reside en la etiqueta <template> y una parte funcional en la etiqueta <script>. Si estamos trabajando con la versión Vue 2, probablemente estemos utilizando la Options API, por lo que tendremos un objeto con propiedades de Vue: name (nombre del componente), data (variables de Vue), methods (funciones de Vue), etc...

Sintaxis de plantillas (mustache)

Vue nos permite hacer referencia a las variables (o métodos, propiedades computadas, etc...) de Vue desde la parte de templates, simplemente escribiéndolo entre {{ dobles llaves }}, lo que se conoce como sintaxis de plantillas o formato mustache, en referencia a uno de los primeros sistemas de plantillas de Javascript: mustache.

En el siguiente fragmento de código, puedes ver un ejemplo con {{ nickname }}, donde estamos haciendo referencia a la variable nickname del apartado data:

<template>
  <div>
    <div>{{ nickname }}</div>
    <div v-text="nickname"></div> <!-- Equivalente al anterior -->
  </div>
</template>

<script>
  export default {
    name: "Example",
    data() {
      return {
        nickname: "Manz"
      }
    }
  }
</script>

Como se observa, la directiva v-text hace exactamente lo mismo, ya que es realmente lo que utiliza Vue por debajo, utilizando el método nativo .textContent de Javascript.

No obstante, nosotros utilizaremos el formato mustache para hacer referencia a datos y que sea más flexible y fácil de leer. La directiva v-text no se suele utilizar en la práctica.

La directiva v-html

Si quisieramos incluir código HTML en una de esas variables, se mostrarían las etiquetas literalmente. La directiva v-html funciona exactamente igual que v-text, solo que en lugar de mostrar las etiquetas, las procesa y renderiza.

<template>
  <div>
    <!-- Se muestra la etiqueta HTML literalmente -->
    <div>{{ nickname }}</div>
    <!-- Utilizando directiva v-html, se renderiza el HTML -->
    <div v-html="htmlNickname"></div>
  </div>
</template>

<script>
  export default {
    name: "Example",
    data() {
      return {
        nickname: "<strong>Manz</strong>"
      }
    }
  }
</script>

Aún así, lo habitual es no añadir etiquetado HTML en las variables, sino sólo mantener los datos y el etiquetado dejarlo en la parte de las plantillas o crear nuevos componentes para dar formato.

OJO: Si el código HTML es malintencionado (o se puede manipular por parte del usuario), podrían existir problemas de seguridad, ya que podría insertar HTML/CSS/JS no deseado.

La directiva v-pre

En algunas raras ocasiones, podríamos necesitar escribir literal y textualmente el texto {{ nickname }}, por ejemplo, y no querer que se renderice con el valor de la variable nickname. Para conseguir esto, podemos utilizar la directiva v-pre, la cuál evita que se rendericen las plantillas que contenga y las de todos los hijos:

<template>
  <div>
    <div>{{ nickname }}</div>  <!-- Se renderiza al valor de nickname -->
    <div v-pre>{{ nickname }}</div>  <!-- No se renderiza -->
  </div>
</template>

La directiva v-once

Muy similar es la directiva v-once, la cuál permite que se renderice la plantilla que contenga una etiqueta, pero sólo la primera vez. Vue incorpora una característica muy deseable denominada reactividad. Dicha característica permite que, si una de las variables de Vue cambian de valor o contenido, se autoactualizarán en todas las plantillas que hagan referencia a ella, haciendo la actualización de información mucho más cómoda y automática.

Por esa razón, la directiva v-once puede ser interesante en las situaciones en las que solo desees que tome el valor que tiene la primera vez, aunque estos casos suelen ser casos límites muy particulares que se usan muy pocas veces.

La directiva v-cloak

La directiva v-cloak es un atributo que podemos ponerle a un elemento HTML para que Vue, lo elimine automáticamente cuando las plantillas que contenga, se haya procesado. Es decir, el atributo v-cloak permanecerá y cuando se haya cargado completamente, se eliminará de la etiqueta.

Esto puede resultar interesante para darle estilo mediante CSS con un selector del tipo [v-cloak] y realizar operaciones como ocultar el elemento mientras no esté listo (o cosas similares).

La directiva v-model

Probablemente, una de las directivas básicas más interesantes sea v-model. Esta directiva permite crear un modelo de datos bidireccional entre un elemento HTML concreto y una variable de Vue. ¿Qué significa esto? Significa que podemos sincronizar el contenido de una variable con el contenido que tenga un elemento HTML <input> (por ejemplo) en su atributo value.

Veamos un ejemplo utilizando la directiva v-model con una etiqueta de campo de datos <input>:

<template>
  <div>
    <div>{{ userdata }}</div>
    <input v-model="userdata" />
  </div>
</template>

<script>
  export default {
    name: "Example",
    data() {
      return {
        userdata: "Valor de ejemplo"
      }
    }
  }
</script>

Observa que tenemos una template mustache con la variable userdata y en el <input> usamos la directiva v-model apuntando también a userdata. Lo interesante de este ejemplo es que podemos modificar el campo del <input> y veremos que se modifica automáticamente el contenido del <div> anterior al detectar cambios. Esto es un ejemplo de una de las características estrella de Vue, la reactividad.

Igual que hemos utilizado la directiva con una etiqueta <input> por defecto (de tipo texto), podemos usarla con otras modalidades como podrían ser <input type="radio">, <input type="checkbox"> los cuales se guardarían como o <input type="color">, que se guardaría en un .

Además, esta directiva tiene ciertos modificadores con los que puedes cambiar el comportamiento por defecto de la directiva (se colocaría justo después de v-model):

Modificador Descripción
.lazy En lugar de actualizar en cada tecla (onInput), lo hace cuando el usuario cambia el foco (onChange).
.number Traduce el contenido de a (sólo si es un número válido).
.trim Recorta los espacios en blanco a los lados del contenido de texto.

La directiva v-model puede funcionar con elementos <input>, pero también con elementos <select>, <textarea> e incluso con componentes definidos por nosotros (que veremos un poco más adelante). Veamos un nuevo ejemplo, ahora con una etiqueta <textarea>, para campos de texto más extensos:

<template>
  <div>
    <div>{{ userdata }}</div>
    <textarea v-model.lazy="userdata" cols="80" rows="5"></textarea>
  </div>
</template>

<script>
  export default {
    name: "Example",
    data() {
      return {
        userdata: "Valor de ejemplo"
      }
    }
  }
</script>

Aquí vemos que hemos utilizado el modificador .lazy, por lo que el texto que escribamos en el <textarea> no se irá modificando en cada pulsación, sino que se actualizará cuando pulsemos TAB o salgamos del campo de texto (pierda el foco). Esto puede ser útil en algunas situaciones donde no queremos que dispare una función asociada muchas veces, o simplemente queremos que se actualice el texto sólo al salir del campo.

Listas de selección con v-model

Veamos ahora un ejemplo utilizando la directiva v-model con una etiqueta de selección de opciones <select>. En este caso, la directiva v-model hará referencia a una variable que guardará el valor (atributo value) de la opción seleccionada:

<template>
<div>
  <div></div>
    <select v-model="listItems">
      <option value="A">Product A</option>
      <option value="B">Product B</option>
      <option value="C">Product C</option>
    </select>
  </div>
</template>

<script>
  export default {
    name: "Example",
    data() {
      return {
        listItems: "C"
      }
    }
  }
</script>

Más adelante, cuando veamos las directivas de bucle v-for veremos como separar la lógica (con los datos) del etiquetado de código, manteniendo la información en las variables de Vue y recorriendo dicha estructura desde el etiquetado de plantillas de Vue.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev