i

Vue Custom Elements

Es ist möglich, mithilfe des Frameworks Vue interaktive Elemente für inf-schule zu erstellen. Man spricht in diesem Zusammenhang von Custom Elements. Um den Umgang mit Vue zu lernen, bietet sich die offizielle Dokumentation an. Diese Anleitung konzentriert sich auf die Einbindung von Elementen in inf-schule.

Vorbereiten des Projektes

Navigiere im Terminal in ein Verzeichnis, in dem der Projektordner erstellt werden soll. Das Projekt wird dann mit dem Befehl npm create vue@latest initiiert. Die folgende Konfiguration sollte gewählt werden:

  1. Projektname: Der gewünschte Projektname, der entsprechende Unterordner bekommt den gleichen Namen.
  2. TypeScript ist optional.
  3. Die restlichen Punkte können mit No beantwortet werden.

Anschließend wird das Projekt vorbereitet. Die Befehle sollten ohne Fehler ausgeführt werden. Sollten Fehler auftreten, fehlen eventuell noch Pakete, die dann nachinstalliert werden müssen, und anschließend muss das Projekt neu initiiert werden.

Test der Entwicklungsumgebung

Die Entwicklungsumgebung bietet die Möglichkeit, das Projekt lokal ohne weiteren Webserver zu testen. Dafür im Terminal in das Verzeichnis des Projektes navigieren und den Befehl npm run dev ausführen. Nach ein paar Sekunden sollte im Terminal nun eine Adresse und ein Port erscheinen, unter dem das Projekt erreichbar ist, falls es keine Fehler gibt. Die Seite kann mit dem Buchstaben "o" geöffnet werden. Der Server kann im Hintergrund weiterlaufen und überwacht die Änderungen im Projekt. Wird eine Projektdatei verändert und gespeichert, so wird das Projekt aktualisiert und die Seite im Brower neu geladen, sodass die Änderungen direkt geprüft werden können. Den Server beendet man wie üblich über die Tastenkombination "control + c" oder mit dem Buchstaben "q".

Konfiguration als Custom Element vornehmen

Der Befehl npm run build erzeugt aktuell noch eine komplette Vue-App, die sich nicht als einzelnes Element in inf-schule einbauen lässt. Folgende Änderungen sind dafür nötig:

./src/main.ts oder ./src/main.js

In dieser Datei wird festgelegt, welche Komponenten des Projektes in der späteren Datei vorhanden sein sollen. In Zeile 8 wird ebenfalls der HTML-Tag festgelegt, über den die Komponente eingebunden werden kann. Die Zeile 3 sowie die Zeilen 7 und 8 müssen für alle Komponenten kopiert und angepasst werden, die später als Element in inf-schule aufrufbar sein sollen.

import { createApp, defineCustomElement } from 'vue'
import App from './App.vue'
import Komponente1 from './components/Komponente1.vue'

createApp(App).mount('#app')

const FullNameElement = defineCustomElement(Komponente1);
customElements.define('komponente-1', FullNameElement);

./vite.config.ts oder ./vite.config.js

In dieser Datei wird festgelegt, dass ein Custom Element erstellt werden soll. Einige Zeilen sind schon vorhanden, ein paar Dinge müssen ergänzt werden. Hier der komplette Code der Datei:

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

const customElementFlag = process.argv.includes("--custom-element")

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue({
      customElement: customElementFlag,
    }),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  build: {
    rollupOptions: {
      // für deterministische Dateinamen, siehe hier:
      // https://github.com/vitejs/vite/issues/378#issuecomment-789366197
      output: {
        entryFileNames: `[name]-[hash].js`,
        chunkFileNames: `[name]-[hash].js`,
        assetFileNames: `assets/[name].[ext]`,
      },
    },
  },
})

./package.json

In dieser Datei müssen nur zwei Zeilen verändert werden, damit bei der Ausführung von npm run dev und npm run build auch das Custom Element erstellt wird:

...
"dev": "vite",
...
"build-only": "vite build -- --custom-element",
...

./src/App.vue

Diese Datei enthält die Elemente, die lokal beim Befehl npm run dev angezeigt werden sollen. Im einfachsten Fall wird nur eine einzelne Komponente eingeladen (hier Komponente1):

<script setup>
import Komponente1 from './components/Komponente1.vue'
</script>

<template>
  <Komponente1/>
</template>
Optional für TypeScript: <script setup><script setup lang="ts">

Mit dem vorgeschlagenen Vorgehen werden die Elemente im Testmodus (npm run dev) nicht als Custom Element, sondern direkt in die Testseite integriert. Das erleichtert das schnelle Testen von Veränderungen im Code, aber kann zu inkonsistentem Verhalten zwischen beiden Modi führen: Im Gegensatz zur direkten Einbindung wird bei der Einbindung per Custom Element zur Kapselung ein Shadow DOM erzeugt. Dadurch werden beispielsweise HTML-Elemente innerhalb der Komponente nicht direkt mit document.getElementById & Co. gefunden (sollte in der Regel auch nicht nötig sein, aber kann zu Kompatibilitätsproblemen mit Bibliotheken führen).

Um auch im Testmodus ein Custom Element einzuladen:

  • Das Flag --custom-element auch für den Testmodus setzen (siehe ./package.json)
  • In ./src/App.vue das Element mit dem HTML-Tag für das Custom Element einladen (etwa <komponente-1></komponente-1> statt <Komponente1/>)

Custom Element erstellen

Damit das Element erstellt wird, muss der Befehl npm run build ausgeführt werden. Es wird der Ordner ./dist/ erstellt. Wichtig für inf-schule ist nur die Datei ./dist/index.js.

Custom Element auf inf-schule einbinden

Damit das Element auf einer Inhaltsseite genutzt werden kann, müssen folgende Dateien geändert werden:

Vue-Projekt ./dist/js/index.js → inf-schule ./assets/thirdparty/projektname/js/

Die Datei ./dist/js/index-[hash].js muss im inf-schule-Repository unter ./assets/thirdparty/projektname/js/ abgelegt werden.

./site/plugins/inf-schule/config/features.json

Das Feature muss registriert werden. Dafür muss die Datei ./site/plugins/inf-schule/config/features.json angepasst werden. Hier wird der Ordner zur benötigten JavaScript-Datei im JSON-Format dem Featurenamen zugeordnet:

"projektname": {
    "jsModuleFolder": [
        "assets/thirdparty/projektname/js/"
    ]
}
Damit das Element auf einer Inhaltsdatei genutzt werden kann, muss es über das Attribut features geladen werden. In unserem Beispiel über features: projektname. Das Element kann jetzt an passender Stelle in der Inhaltsdatei über das festgelegte HTML-Tag eingebunden werden, in unserem Beispiel <komponente-1></komponente-1>.

Suche

v
15.6.3.4.13
inf-schule.de/infschule/dokumentation/kapitel-erstellen/interaktive-elemente/vue-ce
inf-schule.de/15.6.3.4.13
inf-schule.de/@/page/7Q7wkgMRtijgvkuz

Rückmeldung geben