Atributos, clases y estilos dinámicos en VueJS

Última actualización:

Atributos en el HTML

Con Vue tienes la posibilidad de poner atributos HTML como el src de una imagen de tal forma que su valor venga desde Variables de Vue, Métodos de Vue y Computadas de Vue

La forma de conseguir esto es unsando la notación de los dos puntos, en el ejemplo del src de una imagen sería :src.

Dentro, entre comillas se pone directamente el valor de la variable o computada (si es un método se pone entre paréntesis):

<template>
  <div class="content">
    <img :src="source" />
  </div>
</template>

<script>
export default {
  data: () => ({
    source: "https://i.imgur.com/BBcy6Wc.jpg"
  })
};
</script>

<style scoped>
</style>

Esto se puede hacer con cualquier propiedad de las nativas de HTML, por ejemplo:

<template>
  <div class="content">
    <img :src="source" :class="myClass" />
  </div>
</template>

<script>
export default {
  data: () => ({
    source: "https://i.imgur.com/BBcy6Wc.jpg",
    myClass: "my-class"
  })
};
</script>

<style scoped>
</style>

Si por ejemplo no pongo los dos puntos antes de la clase, la clase que tendría en la página sería myClass literalmente y no la variable que queremos que coja.

Por cierto, como pasa al pintar variables entre llaves, dentro de las comillas puedes usar Javascript para hacer pequeños ajustes, por ejemplo añadir al valor de la variable un string:

<img :src="source + '.jpg' " />

Ojo con esto porque tienes que poner los strings con comillas simples para que no confronte con las comillas dobles del atributo.

Como Vue es reactivo, si en algún punto la variable se actualiza con un nuevo valor en la lógica del componente, la vista se actualizará con el nuevo valor de la variable sin que lo tengas que cambiar a mano.

Clases dinámicas

Poner clases que vengan desde datos de la lógica de componentes es igual que con el resto de atributos:

<div :class="myClass + '-active' "></div>

Pero todavía se pueden hacer más cosas con las clases, como pasar un objeto con una serie de keys que serán las clases que queremos añadir:

<template>
  <div class="content">
    <img :src="source" :class="classObject" />
  </div>
</template>

<script>
export default {
  data: () => ({
    source: "https://i.imgur.com/BBcy6Wc.jpg",
      classObject: {
      active: true,
      "text-danger": false
    }
  })
};
</script>

<style scoped>
</style>

En este caso el valor de la clase es un objeto y no un string. Dentro del objeto como propiedad pones el valor que quieres que tenga y true o false para decidir si se usa esa clase o no.

Si te fijas el nombre de la segunda clase está entre comillas, esto se hace para que se pueda usar el guión, de lo contrario salta error porque no se puede crear una clave con guión en objetos Javascript.

También puedes crear este tipo de objetos directamente en la vista:

<template>
  <div class="content">
    <img :src="source" :class="{active: isActive, danger: isDanger} " />
  </div>
</template>

<script>
export default {
  data: () => ({
    source: "https://i.imgur.com/BBcy6Wc.jpg",
    isActive: true,
    isDanger: false
  })
};
</script>

<style scoped>
</style>

Estilos inline dinámicos

De la misma manera que con las clases, también podemos crear estilos inline que vengan de la lógica del componente:

<template>
  <div class="content">
    <div :style="styleObject"></div>
  </div>
</template>

<script>
export default {
  data: () => ({
    source: "https://i.imgur.com/BBcy6Wc.jpg",
    styleObject: {
      background: "red",
      width: "300px",
      height: "30px",
      fontSize: "13px"
    }
  })
};
</script>

<style scoped>
</style>

Como puedes ver, cuando necesitas meter un estilo que tiene un nombre con guión, como por ejemplo, font-size, lo tienes que meter en camelCase para que Vue lo cambie por el nombre correcto

Como antes, también los puedes meter directamente en la vista si lo prefieres:

<template>
  <div class="content">
    <div :style="{width: '200px', height: '40px', background: 'blue'}"></div>
  </div>
</template>

<script>
export default {
  data: () => ({
    source: "https://i.imgur.com/BBcy6Wc.jpg"
  })
};
</script>

<style scoped>
</style>

También puedes pasar un array a los estilos para usar varios objetos a la vez:

<div :style="[baseStyles, overridingStyles]"></div>

En este caso se hará un merge de los objetos para generar los estilos, en este ejemplo los valores de overridingStyles sobreescribirán a los del otro objeto.

Conclusiones

Toda esta parte de la vista es muy potente y es una de las cosas que más me gusta de Vue (y de otros frameworks).

Puedes configurar en la vista los atrubitos y las clases tirando de datos del componente para que luego simplemente cambiando los datos se te actualice la vista con lo nuevo, sin tener que andar modificando y borrando clases a mano.