La directiva v-bind (dos puntos) es una de las directivas más utilizadas y populares de Vue. Esta directiva permite enlazar (bindear) una variable de Vue con un atributo específico de una etiqueta HTML. De esta forma, podemos colocar como valor de un atributo HTML el contenido que tengamos almacenado en una variable de la lógica de Javascript.

Bindeo de atributos (directiva v-bind)

Esta forma de trabajar hace que todo sea mucho más dinámico, a la vez que sincroniza datos de Javascript con estructura y marcado de HTML, lo que junto al sistema de reactividad de Vue, es toda una ventaja que nos hará trabajar más rápido.

¿Cómo funciona v-bind?

Observemos el siguiente ejemplo. De esta forma se puede definir una imagen en HTML estático:

<img src="https://lenguajejs.com/javascript/logo.svg" alt="Logo de Javascript">

Ahora, nuestra intención es que esos datos, esa información (url de la imagen, texto alternativo) se encuentre en Javascript, de modo que separemos la estructura de la información y los datos. Primero pasemos el ejemplo estático a Vue.

Observa que también hemos creado las variables de Vue con nombre image y text, aunque de momento no las estamos usando en el template:

<template>
  <div>
    <img src="https://lenguajejs.com/javascript/logo.svg" alt="Logo de Javascript">
  </div>
</template>

<script>
export default {
  data() {
    return {
      image: "https://lenguajejs.com/javascript/logo.svg",
      text: "Logo de Javascript"
    }
  }
}
</script>

Ahora es cuando entra en juego la directiva v-bind. Observa que la vamos a utilizar dos veces, una para el atributo src (que recogerá el contenido de la variable image) y otra para el atributo alt (que recogerá el contenido de la variable text).

Ten en cuenta que estos datos pueden ser tanto recogidos de variables que figuren en data (como las de este ejemplo) así como que figuren en props:

<template>
  <div>
    <img v-bind:src="image" v-bind:alt="text">
  </div>
</template>

<script>
export default {
  data() {
    return {
      image: "https://lenguajejs.com/javascript/logo.svg",
      text: "Logo de Javascript"
    }
  }
}
</script>

OJO: La directiva v-bind se puede abreviar simplemente omitiendo v-bind y manteniendo solamente los dos puntos (:). Esta es la sintaxis más frecuente y la que comenzaremos a usar.

Bindeo dinámico

En algunos casos que nos interesen, podríamos utilizar los corchetes para indicar que recoja el atributo de una variable, pudiendo hacer este proceso aún más dinámico:

<template>
  <div>
    <img v-bind:src="image" v-bind:[key]="text">
    <img :src="image" :[key]="text"> <!-- Equivalente al anterior -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      key: "alt",
      image: "https://lenguajejs.com/javascript/logo.svg",
      text: "Logo de Javascript"
    }
  }
}
</script>

En este caso, estamos obteniendo un atributo alt="Logo de Javascript", pero si cambiamos la variable key por title (por ejemplo), obtendremos el atributo title="Logo de Javascript".

Bindeo de objetos

Otro caso interesante podría ser el de enlazar completamente una etiqueta HTML con un objeto que tenemos en las variables de Vue. De esta forma actualizamos la etiqueta completa simplemente actualizando el desde Javascript. Veamos el ejemplo anterior aplicando este concepto:

<template>
  <div>
    <img v-bind="image">
    <img :="image"> <!-- Equivalente al anterior -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      image: {
        src: "https://lenguajejs.com/javascript/logo.svg",
        alt: "Logo de Javascript"
      }
    }
  }
}
</script>

Lo importante en este ejemplo es darse cuenta que las claves (propiedades) del objeto deben coincidir con los atributos que queremos utilizar.

Bindeo de clases (:class)

Ahora que sabemos utilizar la directiva v-bind o : con atributos genéricos de una etiqueta, vamos a ver casos especiales con el bindeo del atributo class de una etiqueta, utilizada para añadir clases CSS a un elemento HTML.

<div :class="className"></div>

Dependiendo del tipo de dato de className, Vue actuará de una forma u otra respecto a asignar una clase al elemento. Las posibilidades son las siguientes:

Caso Tipo de dato Descripción
1 className Aplica la clase indicada en className al elemento <div>.
2 className Aplica todas las clases contenidas en className a la vez.
3 className Aplica todas las clases (el nombre de la key) que estén a true en className.

Veamos un ejemplo de cada uno en el siguiente fragmento de texto (ten en cuenta que no puede existir la misma key className varias veces en data, es un ejemplo de cada caso):

export default {
  data() {
    return {
      className: "red",             /* Caso 1 */
      className: ["red", "blue"],   /* Caso 2 */
      className: {                  /* Caso 3 */
        red: true,
        blue: false
      }
    }
  }
}

Obviamente, en este caso, las clases red o blue deben existir en la sección <style> del componente, ya que se aplican pero deben definirse allí. Sin embargo, es posible que en lugar de clases, te interese aplicar este mismo concepto a la etiqueta style de estilos en línea de CSS. Para ello, tenemos el siguiente apartado.

Bindeo de estilos (:style)

Si lo que nos interesa es aplicar propiedades específicas en lugar de clases CSS, podemos hacer un bindeo del atributo style, de la misma forma que hicimos con :class. De esta forma, añadimos las propiedades CSS que existan en la variable a la que hacemos referencia.

<div :style="styles"></div>

En este caso, también depende del tipo de dato de la variable styles:

Caso Tipo de dato Descripción
1 styles Aplica las propiedades CSS contenidas en el string styles.
2 styles Aplica todas las clases contenidas en styles a la vez.
3 styles Aplica todas las clases (el nombre de la key) que estén a true en styles.

Veamos un ejemplo de cada uno en el siguiente fragmento de texto (al igual que antes, no puede existir la misma key styles varias veces en data, es sólo un ejemplo múltiple):

export default {
  data() {
    return {
      styles: "background: red",                    /* Caso 1 */
      styles: ["background: red", "color: white"],  /* Caso 2 */
      styles: {                                     /* Caso 3 */
        background: "red",
        color: "white",
        padding: "8px"
      }
    }
  }
}

Si te ha resultado útil este apartado, es muy posible que te interese profundizar en un concepto llamado CSS-in-JS. Una de las librerías agnósticas más populares es Emotion.

¿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