Componentes globales en Vuejs

Los componentes son la piedra angular del desarrollo web. Es así que la mayoría de plataformas web hoy en día están basados en componentes, ya que estos nos ayudan a reutilizar código y ser más eficientes en el desarrollo. Pero cada vez que queramos utilizarlos dentro de nuestro proyecto es importante reutilizarlos. Sin embargo, existe un tipo de componente que no necesita ser importado antes de usarlo. Estos son conocidos como componentes globales.

En este tutorial aprenderemos a crear componentes globales en Vuejs y como ejemplo crearemos un componente global para íconos.

Índice

  1. Declarando el componente global
  2. Registro automático de componentes globales
  3. Creando un componente global de íconos
  4. Tu turno

1. Declarando el componente global

En vuejs para usar un determinado componente dentro de una vista, primero tenemos que importarlo, luego declararlo en el componente o vista donde se mostrará y por ultimo utilizarlo. Veremos ahora un método que nos permitirá registrar nuestro componente de una forma global, de tal manera que no necesitemos hacer el import cada vez que queramos utilizarlo.

Para lograr esto, debemos registrar al componente que queramos que sea global dentro del archivo main.js. Veamos un ejemplo de cómo registrar un componente.

import Vue from 'vue'
import App from './App.vue'
import BaseIcon from './components/BaseIcon'

// Como parámetro primero le pasamos el nombre y luego el componente
Vue.component('BaseIcon', BaseIcon)

...

Luego de hacer esto, solo bastaría con llamar a las etiquetas <base-icon></base-icon> desde cualquier componente o vista, sin necesidad de hacer un import.

2. Registro automático de componentes globales

El anterior fue la forma simple y directa de hacer un componente global. Sin embargo, podemos automatizar el proceso, para que cualquier componente cuyo nombre comience, por ejemplo, con base o global, se haga global automáticamente.

Este es un proceso de automatización en el cual nos ayudaremos de una librería muy utilizada en JavaScript llamada lodash. Esta librería trae consigo funciones y herramientas para trabajar con strings, arreglos, etc. Entonces lo primero que haremos será instalar lodash utilizando el siguiente comando.

npm i lodash

Entonces, aqui también trabajaremos en el archivo main.js y comenzaremos agregando dos funciones de la librería lodash que acabamos de instalar.

import upperFirst from "lodash/upperFirst";
import camelCase from "lodash/camelCase";

La segunda herramienta que nos ayudará es Webpack que como sabemos es el empaquetador que utiliza vue create para unir todas las partes de nuestro proyecto por lo que no necesitamos instalarlo.

Entonces, comenzaremos utilizando el require.context() de Webpack para tomar la referencia de un directorio y buscar archivos .vue que tengan la palabra Base al inicio.

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import upperFirst from "lodash/upperFirst";
import camelCase from "lodash/camelCase";

const requireComponent = require.context(
  // La ruta relativa donde se encuentran nuestros componentes
  "./components",
  // El parámetro que indica si buscaremos dentro de subforderes de la carpeta
  false,
  // La expresion regular que indica las caracteristicas del nombre de nuestro archivo
  /Base[A-Z]\w+\.(vue|js)$/
);

La variable requireComponent contiene un arreglo con los archivos cuyo nombre comienzan por Base. Para obtener este arreglo utilizamos keys(). Esto nos entregará un arreglo de strings de la siguiente forma.

["./BaseIcon.vue", "./BaseNombre.vue"]

Asi que lo siguiente será hacer un forEach() sobre dicho arreglo, primero para obtener la configuración que webpack nos brinda sobre cada archivo. Para esto utilizamos requireComponent(). Segundo, para obtener el nombre en formato PascalCase del componente. Y tercero, para registrar dicho componente con su respectiva configuración en la instancia de Vue.

requireComponent.keys().forEach((fileName) => {
  // Obtener la configuración del componente
  const componentConfig = requireComponent(fileName);

  // Obtener el PascalName del componente
  const componentName = upperFirst(
    camelCase(
      // Oteniendo el nombre del archivo independiente de la profundidad
      // de su ubicación
        .split("/")
        .pop()
        .replace(/\.\w+$/, "")
    )
  );

  // Registrar el componente
  Vue.component(
    componentName,
    // Aquí se buscarán las opciones del componente en .default del componentConfig
    // este existe si es que el componente fue exportado usando export default
    // En caso de no encontrarlo utilizará las opciones de la raiz de componentConfig
    componentConfig.default || componentConfig
  );
});

Listo!! ahora todos los componentes que empiezan por Base como BaseIcon.vue o BaseCard.vue ya son detectados automáticamente y no necesitan un import en las vistas o componentes donde los queramos usar. Simplemente colocamos la etiqueta <base-icon></base-icon> y listo.

3. Creando un componente global de íconos

Ahora crearemos un componente global para poder usar iconos en cualquier parte de nuestro proyecto sin necesidad de importar ningún componente.

Primero instalaremos feather-icons, que es una librería de iconos que utilizaremos en nuestro componente global, para esto utilizamos el siguiente comando.

npm install feather-icons

Luego de esto crearemos el componente BaseIcon.vue que contendrá el siguiente código. Este será nuestro componente global de iconos.

<template>
  <div class="icon-wrapper" v-html="svg">Icon</div>
</template>

<script>
  import feather from "feather-icons";

  export default {
    props: {
      name: String,
      width: {
        type: [Number, String],
        default: 24,
      },
      height: {
        type: [Number, String],
        default: 24,
      },
    },
    computed: {
      svg() {
        return feather.icons[this.name].toSvg({
          class: "icon",
          width: this.width,
          height: this.height,
        });
      },
    },
  };
</script>
<style scoped>
  .icon-wrapper {
    display: inline-flex;
    align-items: center;
    color: rgba(0, 0, 0, 0.4);
    font-size: 1rem;
    font-weight: 600;
    margin-right: 6px;
  }
  .icon {
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: none;
  }
</style>

Lo siguiente es agregar el código que vimos anteriormente para reconocer los archivos que comienzan con Base como iconos globales. Así que nuestro archivo main.js debe quedar así.

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import upperFirst from "lodash/upperFirst";
import camelCase from "lodash/camelCase";

const requireComponent = require.context(
  "./components",
  false,
  /Base[A-Z]\w+\.(vue|js)$/
);
requireComponent.keys().forEach((fileName) => {
  const componentConfig = requireComponent(fileName);
  const componentName = upperFirst(
    camelCase(
      fileName
        .split("/")
        .pop()
        .replace(/\.\w+$/, "")
    )
  );

  Vue.component(componentName, componentConfig.default || componentConfig);
});

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

Y ya podremos utilizar el componente <base-icon></base-icon> en cualquier lugar de nuestro proyecto sin necesidad de importar ningún archivo. Veamos el siguiente ejemplo donde utilizamos el ícono users.

<base-icon name="users"></base-icon>

4. Tu turno

Ahora que ya sabes crear componentes globales, prueba creando una librería propia de componentes básicos pero muy utilizados que no necesiten de un import para llamarlos. Por ejemplo, botones, cards, títulos, etc. Estos son componentes que casi todas tus vistas utilizarán y es más productivo tenerlos listos para utilizar que importarlos cada vez que quieres utilizarlos.