Wie bereits in Teil 1 dieser Blogreihe erwähnt kann Vue.js in TypeScript Projekten eingesetzt werden. Die Frage die sich jedoch stellt ist das Wie. Anhand eines Beispiels werde ich Ihnen zeigen, wie ich es in einem Kundenprojekt gelöst habe.
Die Voraussetzung für den Einsatz von Vue.js in Type Script Projekten ist, dass das Projekt bereits ein Basis-Setup hat:
- .ts Dateien werden in .js Dateien kompiliert
- die .js Dateien werden von ES6 nach ES5 umgewandelt (nicht alle Browser unterstützen ES6 Features)
- die .js Dateien werden zu einer Datei gebündelt (nicht concatenated, sondern nach den verwendeten Modulen aufgelöst)
- (es werden zu den kompilierten .ts Dateien Sourcemaps generiert)
Ich habe für das Basis-Setup des Beispiel Projekts folgendes verwendet:
- Npm zum Installieren aller nötigen Pakete
- Gulp als Task-Runner Tool
- Tsify zum kompilieren der .ts Dateien in .js Dateien (ist ein Plugin für Browserify)
- Babel bzw. Babelify (ist ein Plugin für Browserify) zum Umwandeln von es6 Modulen
- Browserify zum Bündeln der Dateien (löst die imports der Dateien auf und erstellt basierend darauf eine Datei. Ist ein Pendant zu webpack)
- Exorcist zum Erstellen von externen Sourcemaps (Browserify erstellt standardmäßig inline sourcemaps, was die Dateien sehr groß macht > ist nicht zu empfehlen!).
Installieren von Vue.js über npm
npm install --save vue@2.5.13
Prinzipiell verweist das Modul ‘vue’ auf die Datei vue.runtime.js. Dies ist eine der Versionen, die Vue.js zum Einbinden zur Verfügung stellt. Da wir jedoch nicht das gesamte Rendering selbst übernehmen, benötigen wir nicht die vue.runtime.js Datei, sondern vue.esm.js. Nähere Informationen zu den unterschiedlichen Builds können dem Vue.js Guide entnommen werden.
Je nachdem welches Basis Setup verwendet wird, muss diese “Umleitung” anders konfiguriert werden. Bei Browserify wird dies über die Methode .require() gemacht:
gulp.task('compile', function(){ var b = browserify(); ... b.require("./dest/vue.esm.js", {expose: "vue"}); ... });
Im Vergleich zu Webpack kann Browserify nicht mit ES6 Modulen umgehen. Daher muss die Datei vue.esm.js mittels Babel umgewandelt werden, bevor Browserify diese “Umleitung” macht.
// Vue needs to be converted // Browserify cannot work with es6 modules. Must be converted via babel before bundling(). gulp.task('convertVue', function(){ return gulp.src('./node_modules/vue/dist/vue.esm.js') .pipe(babel({ presets: ['env'] }) .pipe(gulp.dest('./dest'))); });
Erstellung eines Vue Controllers
Damit Vue.js klassenbasiert verwendet werden kann muss eine Klasse lediglich von Vue erben und im Konstruktor den super() Konstruktor aufrufen. Vue.js bietet die Möglichkeit bereits zu Beginn eine leere Instanz zu erstellen, jedoch würde ich davon abraten und gleich beim Intanzieren die wichtigsten Informationen übergeben – wie beispielsweise die option ‘el’.
// Klasse wurde unter ./src/Controller/AppController.ts erstellt import Vue from 'vue'; export default class AppController extends Vue { constructor() { // add Vue Properties super({ el: '#app', }) } }
Dem super() Konstruktor können alle Optionen, welche auch bei einer klassischen Vue Instanzierung Verwendung finden, übergeben werden. Der Unterschied ist der, dass in diesem Beispiel der AppController zur Vue Instanz wird.
In dem Beispielprojekt ist der AppController die “oberste” Instanz über die die Applikation gesteuert wird. Was genau ist damit gemeint? Standardmäßig wird in jedem TypeScript Projekt eine index.ts gesucht. Diese Datei ist die “Einstiegs-Datei”. In dieser wird eine Instanz des AppControllers erstellt, welche wiederum im weiteren Verlauf des Projekts alle notwendigen Aktionen ausführt und steuert.
// ./src/index.ts import AppController from "./Controller/AppController"; let app = new AppController(); export default app;
Verwendung von Lifecycle Hooks und von Legacy Code
Vue.js stellt diverse Lifecycle-Hooks zur Verfügung. Diese können im super() Konstruktor wie gehabt aufgerufen werden, nur mit dem Unterschied, dass die Funktion weitere Funktionen – entweder von der Klasse selbst, oder aber anderen Klassen, aufrufen kann.
// ./src/Controller/AppController.ts constructor() { // add Vue Properties super({ el: '#app', mounted: function() { this.callMounted(); } }) } private callMounted() { console.log('Vue Instanz gemounted'); } ….
Dies kann praktisch sein, wenn Vue in bereits bestehende Projekte, die noch Legacy Code enthalten, integriert wird. Bei unserem Kundenprojekt handhaben wir es derzeit so, dass wir in einem Projekt zwei Unterprojekte haben: einerseits für den Legacy Code, der über das Module ‘Legacy’ eingebunden wird und andererseits das neue Projekt, welches auf Legacy, wenn nötig, zugreifen kann.
// ./src/Controller/AppController.ts // es wird direkt auf die index.ts in dem Legacy Projekt zugegriffen, worin sich der export der // Legacy Klasse (oder Klassen) befinden sollte. import Legacy from '../../LegacyProjekt' export default class AppController extends Vue { constructor() { super({ el: '#app', mounted: function() { Legacy.callIfMounted(); } }) } … }
Zögern Sie bitte nicht mich bei Fragen zu kontaktieren, einfach im Beitrag kommentieren, ich freue mich über einen Austausch!
In Teil 3 widmen wir uns der Erstellung einer klassenbasierten Vue.js Komponente, die über den AppController eingebunden wird.
The post Teil 2: Vue.js als Basisklasse in TypeScript Projekten appeared first on ANECON Blog.
Stellen der Anecon Software Design und Beratung GmbH
Testautomatisierer (m/w) in DresdenSoftware Test Manager (m/w) in Dresden
Berufspraktikant (m/w) für den Bereich Testautomatisierung in Dresden
Architekt Testautomatisierung (m/w) in Dresden
Entwickler (m/w) Testautomatisierungs – Frameworks Java/.NET bzw. SAP/ABAP in Dresden