Vue.js: Wie Components bedingt registrieren

Stand Dezember 2020 und Vue.js v2 mit Vue Templates.

TL;DR

  • Erstelle eine Datei um alle Components zu exportieren.
  • Beispiel: Github

Motivation

Als Vue.js 2 live ging, war require der Standard um Dependencies einzubinden. Heute ist es import.

Um imports in Vue.js 2 zu nutzen können wir einfach die Vue Instanz ansprechen und mithilfe von Vue.component einen Namen als auch die Definition der Komponente übergeben.

Das bedeutet wir brauchen zwei Dinge, einen Namen und die Definition.

Wenn wir mit import arbeiten sieht das in etwa so aus:

import AwesomeComponent from './awesome-component';
Vue.component(AwesomeComponent, AwesomeComponent.name, AwesomeComponent);

Stellen wir uns vor, wir bräuchten 20 Komponenten.

Also 20 imports und 20 mal Vue Components hinzufügen.

Hier rennen wir in zwei unpraktische Dinge:

  • Wir verlieren schnell den Überblick, resultiert in aufwändiger Wartbarkeit.
  • Durch export default haben wir lediglich ein JSON und kein Objekt vom Typ AwesomButton. Was wiederum darin resultiert, das wir keine Sicherheit haben, dass die Variable AwesomeButton auch wirklich ein AwesomeButton ist.

Diese zwei Punkte haben mich längere Zeit geärgert.

Es wäre cool, wenn wenige Zeilen ausreichen würden um Komponenten zu registrieren.

Und so begann ich zu graben

Annahmen

Nehmen wir an wir hätten folgende Ordnerstruktur:

├── node_modules/
├── package.json
├── public/
│   ├── assets/
│   └── index.html
├── resources/
│   └── js/
│       ├── application.js
│       └── components/
│           ├── awesome-button/
│           └── index.js
└── webpack.config.js

Was wäre wenn wir ein richtig gutes Array hätten?

Wir wissen was wir brauchen um eine Komponente zu registrieren. Und Webpack kann krasse Ding mit export anstellen.

Ergo, können wir versuchen ein Array mit Inhalten zusammen zu stellen.

Ein Inhalt wären Dinge womit Vue arbeiten kann.

Theoretisch, möglich, praktisch brauchen wir:

  • Mindestens eine Vue Component (components/awesome-button/index.js.
<template>
  <button><slot></slot></button>
</template>

<script>
export default {
  name: 'awesome-button',
}
</script>
  • Eine Datei die alle Komponenten exportiert (components/index.js).
export { default as AwesomeButton } from './awesome-button';
// export {default as AwesomeForm} from './awesome-form';
  • Eine Funktion die eine Komponente registriert.
function registerComponent(component) {
    Vue.component(component.name, component);
}

Haben wir das, importieren wir noch die Components und registrieren diese in unserem Einstiegspunkt.

Zum Beispiel (application.js) so:

import Vue from 'vue';

// Get all components.
import * as components from './components';

// Register each component.
Object.values(components)
    .forEach(registerComponent);

// Callback to register a single component.
function registerComponent(component) {
    Vue.component(component.name, component);
}

// Inject Vue on DOM element with ID applicationContainer.
const awesomeApplication = new Vue({
    el: '#applicationContainer',
});

BAM!

Und um neue Components zu registrieren, lediglich die components.js anpassen.

Ein Wort der Warnung: So gemütlich es auch ist Komponenten immer von überall abrufbar zu haben, ist es nicht Sinnvoll das auch immer zu tun.

Du solltest es überdenken Dinge die selten sichtbar sind, immer zu registrieren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert