En este artículo vamos a echar un ojo a los componentes web, una pieza fundamental de VueJS y del desarrollo frontend a día de hoy.

Lo primero es, si no lo has leído, que empieces echando un ojo al artículo sobre Introducción a VueJS en el que hacemos una vista de pájaro de lo que puede ofrecer Vue.

Pero antes de ponernos a picar código lo primero es ver lo que es un componente en términos generales ya que es un término que comparten muchos frameworks como Vue, React o Angular.

Qué son los componentes web

Logo componentes web

Los componentes web son un concepto relativamente nuevo, aunque realmente llevas utilizándolos mucho tiempo.

Un componente web se trata de un elemento de la página con vista, estilos y lógica, todo encapsulado, que puedes reutilizar a lo largo de tu página web.

Por ejemplo al crear un elemento HTML <input>, realmente estás creando una especie de componente web porque se compone del HTML que se pinta, los estilos que se pintan por defecto y a lógica de poder escribir.

Pues ahora imagínate que puedes crear tus propias etiquetas HTML y encima con una lógica y estilos más compleja, eso son los webcomponents.

Un ejemplo típico es cuando necesitas en una web un calendario. Creando un componente con toda la lógica y estilos vas a poder reaprovechar este calendario en más sitios de la web sin repetir código.

Los componentes son tan potentes y reutlizables que incluso ya se están añadiendo como estándar web de los navegadores para que se puedan crear en Javascript vanilla.

Antes de empezar como locos a crear componentes échale un ojo a la Estructura de carpetas de un proyecto Vue para que sepas bien en qué carpeta se crean.

Hello world. Cómo se crea un componente

Bien, pues ahora que hemos visto todo lo básico para empezar, vamos a ver por fin algo de código. Lo primero que tienes que hacer tras crear un proyecto es ejecutar en la terminal npm run serve o vue serve para ejecutar vue en modo desarrollo y poder abrir la página que estamos desarrollando.

Si ahora abres localhost:8080 en tu navegador verás la página de prueba de Vue con lo que has instalado. Hora de abrir el proyecto en tu editor de texto favorito, en mi caso el vscode.

Como hemos visto, los componentes se crean dentro de src/components, si abres esa carpeta te encontrarás con un archivo llamado HelloWorld.vue, ábrelo. Verás algo como esto:

<template>
<div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br />
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
    <li>
        <a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a>
    </li>
    <li>
        <a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a>
    </li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
    <li>
        <a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
    </li>
    <li>
        <a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a>
    </li>
    <li>
        <a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a>
    </li>
    <li>
        <a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a>
    </li>
    <li>
        <a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
    </li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
    <li>
        <a href="https://router.vuejs.org" target="_blank" rel="noopener" >vue-router</a>
    </li>
    <li>
        <a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
    </li>
    <li>
        <a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener" >vue-devtools</a>
    </li>
    <li>
        <a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a>
    </li>
    <li>
        <a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener" >awesome-vue</a>
    </li>
    </ul>
</div>
</template>

<script>
  export default {
    name: "HelloWorld",
    props: {
      msg: String
    }
  };
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
  h3 {
    margin: 40px 0 0;
  }
  ul {
    list-style-type: none;
    padding: 0;
  }
  li {
    display: inline-block;
    margin: 0 10px;
  }
  a {
    color: #42b983;
  }
</style>

Lo primero, no te asustes. Lo segundo, borra todo el contenido dentro de las etiquetas <template> y déjalo así:

<template>
    <div class="hello">
    Hello world
    </div>
</template>

<script>
  export default {
    name: "HelloWorld"
  };
</script>

<style scoped lang="scss">
</style>

Si ahora abres [localhost:8080](http://localhost:8080) verás que la página ha cambiado y que ahora pone Hello World

Partes que componen un componente en VueJS

Si recuerdas lo que vimos anteriormente, los componentes se componen de 3 partes: la vista, los estilos y la lógica. Vue para diferencias estas 3 partes usa etiquetas HTML, veamos cada una:

La vista. Template

Dentro de la etiqueta <template> está todo el código HTML que tiene que ver con la vista de un componente.

A diferencia de React, aquí todo el HTML se encuentra dentro del mismo punto, no se pueden crear varios templates. También tienes que saber que en Vue NO se debe insertar nunca HTML desde la lógica del componente, todo el HTML debe estar dentro del template.

Esta parte es la que se suele poner al principio del fichero, antes que la lógica y que los estilos.

La lógica. Script

Aquí es el lugar en el que escribes la funcionalidad, es decir, el comportamiento del componente. Como veremos más adelante, aquí vas a poder controlar qué ocurre cuando se crea el componente, cuando se destruye, cuando cambia una variable, etc.

Por el momento lo que tienes que saber es que siempre que crees un componente tienes que escribir:

<script>
export default {
  name: "HelloWorld"
};
</script>

Esta es la parte mínima de un componente. En la etiqueta name puedes escribir el nombre del componente, pero siempre en PascalCase (la primera letra en mayúsculas, las palabras juntas y cada una con la primera letra en mayúscula). El campo name no es obligatorio pero viene bien para identificar el componente.

A diferencia de Angular, aquí no tienes que indicar explícitamente que coja la vista de otro archivo. Vue ya sabe que la vista para la lógica de este componente está dentro del mismo fichero, en la etiqueta template que hemos visto antes.

Los estilos. Style

Por último están los estilos, dentro de la etiqueta <style>, que se suele poner en el mismo fichero pero debajo del template y de la lógica del componente.

Si al crear el proyecto con Vue CLI 🚧 seleccionaste SASS (o lo instalaste posteriormente) tienes que saber que tienes que incluir dentro de la etiqueta <style> lo siguiente para que puedan funcionar:

<style lang="scss"></style>

Por último te recomiendo que añadas el atrubito scope también a la etiqueta style para poder aislar los estilos del componente. Es decir, los estilos que escribas dentro, si has puesto scope solo van a afectar a ese componente y no al resto de componentes.

Esto de los estilos aislados es muy recomendable para evitar tener componentes con estilos que afecten a otros componentes. Más adelante veremos como crear estilos globales.

Cómo crear un componente nuevo

Para crear los componentes, lo que yo hago es simplemente crear el fichero con el nombre del componente en PascalCase (la primera letra en mayúsculas, las palabras juntas y cada una con la primera letra en mayúscula) y creo la estructura básica con todas las partes. Por ejemplo este componente lo crearía dentro de src/components/ con el nombre MiComponente.vue:

<template>
  <p>Mi primer componente en Vue</p>
</template>

<script>
  export default {
    name: "MiComponente"
  }
</script>

<style lang="scss" scoped>
</style>

Para usar este componente que acabas de crear tienes que hacer lo siguiente. Pongamos que lo quieres insertar en el componente Home de la carpeta /src/views (Si instalaste Vue con el create pero no de la forma manual, o no indicaste que instalara Vue Router puedes importar el componente dentro de App.vue para que veas el ejemplo).

Si abres este componente verás lo siguiente:

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
      <HelloWorld msg="Welcome to Your Vue.js App" />
    </div>
</template>

<script>
  // @ es un alias a /src
  import HelloWorld from "@/components/HelloWorld.vue";

  export default {
    name: "home",
      components: {
        HelloWorld
    }
  };
</script>

Si te das cuenta ya se está usando el componente HelloWorld. Los componentes siempre se importan encima del export dentro de la etiqueta script.

<script>
  // @ is an alias to /src
  import HelloWorld from "@/components/HelloWorld.vue";
  import MiComponente from "@/components/MiComponente.vue";

  export default {
  ...
  }

Como dice el comentario, al importar, dentro de la ruta se coloca @ como atajo a la carpeta src. Esto se suele hacer mucho al programar con Vue.

Ahora toca añadirlo al objeto components de más abajo. Siempre que quieras usar un componente tienes que importarlo y añadirlo aquí, de lo contrario no funcionará.

components: {
  HelloWorld, MiComponente;
}

Por último lo puedes colocar arriba en la vista. Vue por debajo lo que va a hacer es mirar el objeto components que hemos visto antes, y va a sustituir el nombre del componente en PascalCase por el mismo nombre pero en kebab-case. Esto se hace para que cuadren mejor con los elementos HTML. Por lo que solo tenemos que:

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Welcome to Your Vue.js App" />
    <mi-componente></mi-componente>
  </div>
</template>

Como ves también se pueden usar como PascalCase como el componente de HelloWorld pero es más recomendable en kebab-kase: hello-world

Otro detalle a tener en cuenta es que los componentes los puedes cerrar en la misma etiqueta de apertura:

<mi-componente />

Y listo, ya deberías ver el nuevo componente dentro de la página web. Cada vez que cambies algo de unos de los componentes vas a ver el cambio instantáneamente sin tener que recargar la web.

En conjunto quedaría así:

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Welcome to Your Vue.js App" />
    <mi-componente />
  </div>
</template>

<script>
  // @ is an alias to /src
  import HelloWorld from "@/components/HelloWorld.vue";
  import MiComponente from "@/components/MiComponente.vue";

  export default {
    name: "home",
    components: {
      HelloWorld,
      MiComponente,
    },
  };
</script>

Conclusiones

Con esto ya has aprendido a crear tus primeros componentes de Vue, incluso a anidar componentes dentro de otros. Esto es una práctica que recomiendo, crear componentes que se puedan reutilizar en varios sitios para tener el código sin duplicar.

Lo siguiente que deberías aprender es a utlilizar el Sistema de vistas de Vue, es decir, todo lo que tiene que ver con la parte visual del componente.

Si ya conces el sistema de vistas puedes pasar a crear las Variables de Vue y los Métodos de Vue que te servirán para crear la lógica Javascript de los componentes.