
Wie beginnen Sie Ihr Vue.js-Abenteuer?
Front-end-Technologien sind ein Bereich der Softwareentwicklungsbranche, der ständig ein nahezu exponentielles Wachstum erfährt. Immer häufiger entscheiden sich Entwickler bei neuen Projekten dafür, auf reines JavaScript und jQuery zu verzichten und stattdessen moderne Frameworks zur Erstellung der Applikationsschicht zu verwenden. Dann stehen sie vor dem Dilemma – welches soll benutzt werden? Normalerweise werden drei in Betracht gezogen: Vue, React und Angular. In diesem Artikel stellen wir die Grundlagen des ersten davon auf möglichst einfache und freundliche Weise dar.
Was ist Vue.js?
Vue.js, ähnlich wie React.js und Angular, gehört zur Familie der beliebtesten JavaScript-Frameworks für den Aufbau von Benutzeroberflächen. Es ermöglicht Entwicklern, sowohl einfache Komponenten als auch fortgeschrittene und skalierbare Single Page Applications mit zusätzlichen Tools und Bibliotheken zu erstellen.
Vue-Instanz und Templates
Bereits im ersten Stadium unserer Überlegungen müssen wir uns an die Art und Weise gewöhnen, wie das Template mit der JavaScript-Logikschicht verbunden wird. Zu diesem Zweck werden wir die Erstellung einer Vue()-Instanz und ihre grundlegenden Eigenschaften besprechen. Zuerst jedoch müssen wir, um sie in unserem Dokument verwenden zu können, den Code einer Bibliothek einfügen, die beispielsweise von einem CDN verfügbar ist.
HTML
<body>
<div id="app">
<p>{{ message }}</p>
<p>{{ capitalize() }}</p>
<p>{{ reversedMessage }}</p>
</div>
</body>
JavaScript
const app = new Vue({
el: '#app',
data: {
message: 'Hello world',
},
methods: {
capitalize () {
return this.message.toUpperCase()
}
},
computed: {
reversedMessage () {
return this.message.split('').reverse().join('')
}
}
})
Die Hauptaktion, die wir zu Beginn durchführen müssen, ist, das Vue-Objekt mit einem spezifischen DOM-Element in unserem Dokument zu verknüpfen. Die Vue-Instanz muss den Scope kennen, in dem sie arbeiten soll, und dieser muss klar definiert sein. Wir tun dies, indem wir den Namen des Objektel-Selektors angeben, den wir als Argument des Vue()-Konstrukteurs übergeben. Dadurch wird jedes Kind des definierten Elements als virtueller DOM-Baum beobachtet und verarbeitet.
Die data-Eigenschaft enthält Felder, die zur Datenspeicherung verwendet werden, während methods die Definitionen der im Instanzbereich verfügbaren Methoden enthalten. Methoden in computed sind dynamisch berechnete Werte. Wir definieren sie als Methoden, aber wenn sie verwendet werden, nutzen wir sie wie ein reguläres Feld (Vue berechnet diese automatisch). Dies ist äußerst nützlich, beispielsweise in Situationen, in denen Sie einen Wert ändern möchten, aber eine Standardmethode keine optimale Lösung darstellt (zum Beispiel wegen einer großen Anzahl von Abhängigkeiten).
Ein weiteres wichtiges Thema ist die Bezugnahme auf eine der oben genannten Eigenschaften, was mit Hilfe dieses Verweises erfolgt. Dies ist möglich, da Vue alle Eigenschaften mit der Hauptinstanz des Objekts verbindet, was direkten Zugriff auf sie ermöglicht.
Es ist auch erwähnenswert, wie Felder und Methoden im Template verwendet werden. Alles, was im Dokument angezeigt werden soll, wird in doppelte geschweifte Klammern {{ }} gesetzt. Dabei ist nur zu beachten, dass eine solche Syntax nur in verschachtelten #app-Elementen verwendet werden kann.
Direktiven
Direktiven sind spezielle Attribute, die in Templates verwendet werden. Sie werden durch das Präfix v- gekennzeichnet, zum Beispiel: v-if, v-else, v-for, v-model, v-bind. Es ist wichtig, sich daran zu erinnern, dass viele von ihnen Aliase haben, die austauschbar genutzt werden können.
v-if
Ermöglicht die bedingte Darstellung des DOM-Elements, dem die Direktive zugewiesen ist.
HTML
<div id="app">
<p v-if="isVisible">
Ein Absatz
</p>
<button @click="toggle">
Umschalten!
</button>
</div>
JavaScript
const app = new Vue({
el: '#app',
data: {
isVisible: true,
},
methods: {
toggle () {
this.isVisible = !this.isVisible
}
},
})
v-on
Ermöglicht die Anbindung von Event-Listenern an ausgewählte DOM-Elemente.
Alias
v-on:click=”someMethod” -> @click=”someMethod”
HTML
<div id="app">
<p v-if="isVisible">Ein Absatz</p>
<button @click="toggle">Umschalten!</button>
</div>
HTML Version 2
<div id="app">
<p v-if="isVisible">Ein Absatz</p>
<button v-on:click="isVisible = !isVisible">
Umschalten!
</button>
</div>
JavaScript
const app = new Vue({
el: '#app',
data: {
isVisible: true,
},
methods: {
toggle () {
this.isVisible = !this.isVisible
}
},
})
v-for
Ermöglicht die Ausführung einer Schleife auf dem zugehörigen DOM-Element.
HTML
<div id="app">
<p v-for="person in people">
{{ person.name }} ist {{ person.age }} Jahre alt.
</p>
</div>
JavaScript
const app = new Vue({
el: '#app',
data: {
people: [
{ name: 'John', age: 10 },
{ name: 'Mark', age: 20 },
{ name: 'Jeff', age: 30 },
]
},
})
Das Ergebnis
v-bind
Ermöglicht die Bindung an DOM-Elementattribute.
Alias
v-bind:title=”someTitle” -> :title=”someTitle”
HTML Version 1
<div id="app">
<p v-bind:class="className">Ein Absatz</p>
<button @click="toggle">Farbe umschalten</button>
</div>
HTML Version 2
<div id="app">
<p :class="className">Ein Absatz</p>
<button @click="toggle">Farbe umschalten</button>
</div>
JavaScript
const app = new Vue({
el: '#app',
data: {
className: 'red',
},
methods: {
toggle () {
this.className = this.className == 'red'
? 'blue'
: 'red'
}
}
})
v-model
Ermöglicht das Binden von DOM-Elementen wie <input> an Datenobjektfelder.
HTML
<div id="app">
<input type="text" v-model="inputValue" name="exampleInput">
<p>{{ inputValue }}</p>
</div>
JavaScript
const app = new Vue({
el: '#app',
data: {
inputValue: ''
}
})
Komponenten
Komponenten sind Vue-Instanzen, die es Ihnen ermöglichen, Codefragmente auf universelle Weise wiederholt zu verwenden. Dies ermöglicht es Ihnen, Wiederholungen zu vermeiden, wodurch Sie dem DRY-Prinzip (Don't Repeat Yourself) folgen. Dadurch sieht die Anwendung sauber aus und der Code ist lesbar, und falls es nötig ist, müssen Sie keine Fehler an mehreren Stellen beheben.
HTML
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
JavaScript
Vue.component('button-counter', {
data () {
return {
count: 0
}
},
template: `
<button v-on:click="count++">
Sie haben mich {{ count }} mal geklickt.
</button>
`
})
Das Ergebnis
Die Komponente wird mit Vue.component definiert. Das erste Argument der Methode ist der Name des DOM-Elements, das in Templates verwendet werden soll. Der zweite Parameter ist ein Objekt, das in diesem Fall zwei Eigenschaften hat. Die wichtigste davon ist das Template, das bei jeder Verwendung der Komponente im echten DOM-Baum ersetzt wird. Die zweite Eigenschaft des Objekts ist die data-Methode (Methode, nicht das Objekt!), die ein Objekt mit Daten zurückgibt, das für eine einzelne Komponente verfügbar sein wird.
Komponenten können ineinander verschachtelt werden, was es Ihnen ermöglicht, fortschrittlichere und komplexere Template-Strukturen zu erstellen. Das folgende Beispiel zeigt zwei einfache Beispiele: Eltern- und Kindkomponenten. Es wurden spezielle <slot></slot>-Tags verwendet, die als Platzhalter dienen. Alles, was im Elternelement platziert wurde, wird an deren Stelle gerendert.
HTML
<div id="app">
<parent>
<child></child>
<child></child>
<child></child>
</parent>
</div>
JavaScript
Vue.component('parent', {
template: '<div><slot></slot></div>',
})
Vue.component('child', {
template: `<p>Ich bin ein Kind!</p>`
})
const app = new Vue({
el: '#app',
})
Das Ergebnis
Ereignisse
Wir haben sich mit dem Event-Handling beschäftigt, als wir über die v-on-Direktive gesprochen haben. Wir werden sie verwenden, um einen Event-Listener hinzuzufügen, der das Auftreten eines definierten Ereignisses abhört und nach dessen Auslösung eine bestimmte Aktion ausführt (zum Beispiel eine Methode aufruft).
Ein Schritt weiter gedacht, sieht die Kommunikation zwischen Komponenten im Kontext von Ereignissen so aus, dass man sich eine einfache Situation vorstellen kann, in der wir einen DOM-Baum bestehend aus einem Elternelement und einem verschachtelten Kind haben. Die Frage ist, wie man den Eltern darüber informiert, dass ein Ereignis vom Niveau des verschachtelten Elements ausgelöst wurde? Analysieren wir das Beispiel unten.
HTML
<div id="app">
<div>
<example @execute="onExecute"></example>
</div>
</div>
JavaScript
Vue.component('example', {
template: `
<button @click="execute">
Ausführen!
</button>
`,
methods: {
execute () {
this.$emit('execute')
}
}
})
const app = new Vue({
el: '#app',
methods: {
onExecute () {
alert('Führe einige schöne Sachen aus...')
}
}
})
Zuerst einmal ist das Beispiel der Komponente zu beachten, deren Template einen Standard-Button enthält. Die execute-Methode, die eine wesentliche Aktion ausführt, wird aufgerufen, wenn sie geklickt wird. Für das Komponentenobjekt wird die Methode $emit aufgerufen, die ein Ereignis auslöst, das dann von der höheren Komponente abgefangen werden kann. Das erste Argument der Methode ist der Elterneventname @execute. Im zweiten (in diesem Beispiel nicht vorhandenen) können die Daten hinzugefügt werden, die Sie an die vom Elternevent aufgerufene Methode übergeben möchten.
Die obige Methode ist jedoch nicht besonders effektiv, wenn man es mit vielen verschachtelten Komponenten zu tun hat, denn um die erste von ihnen zu informieren, muss man dieses Verfahren mit jedem Kind verwenden. Es ist leicht vorstellbar, welchen negativen Einfluss dieser Ansatz auf die Wartung einer Anwendung haben könnte. Eine der Lösungen für dieses Problem ist die Erstellung einer neuen Vue-Instanz, deren Verknüpfung mit dem globalen Fensterobjekt und dann (basierend auf dem Mechanismus der Verknüpfung aller Objekteigenschaften in Vue) die Verwendung von Methoden wie $emit (zum Auslösen des Ereignisses) und $on (zum Abhören des Ereignisses und Ausführen der Aktion als Reaktion darauf). Auf diese Weise können die Ereignisse, egal wie tief die Komponenten ineinander verschachtelt sind, in der gesamten Anwendung verwaltet werden.
HTML
<div id="app">
<div>
<example></example>
</div>
</div>
JavaScript
window.Event = new Vue()
Vue.component('example', {
template: '<button @click="execute">Ausführen!</button>',
methods: {
execute () {
Event.$emit('execute')
}
}
})
const app = new Vue({
el: '#app',
created () {
Event.$on('execute', () => alert('Führe einige schöne Sachen aus...'))
}
})
Lebenszyklus
Vue hat, ähnlich wie bei React oder Angular, einen Komponentenlebenszyklus und Ereignisse, auf die Sie reagieren können. Beachten Sie alle nennenswerten Methoden, da sie in vielen Standardsituationen äußerst nützlich sind. Ein Beispiel wäre das Laden von Daten aus einer externen API unter Verwendung von AJAX-Anfragen, sobald eine Komponente von Vue erstellt wird. Die am häufigsten verwendeten Objektereignisse sind: created, mounted, updated.
Verwendung in mittelgroßen und großen Anwendungen
Nachdem wir die Grundmechanismen vorgestellt haben, können wir über Themen im Zusammenhang mit den tatsächlichen Methoden des Bauens von Anwendungen in Vue sprechen. Dazu bauen wir eine einfache Anwendung mit der Hilfe von vue-cli – einer Konsolenanwendung basierend auf Node.js, dank der wir unsere Anwendung vom Terminal aus verwalten können. Um vue-cli zu installieren, benötigen Sie Node.js und npm/yarn und dann führen Sie einen der folgenden Befehle aus:
Verwenden Sie die folgenden Befehle, um eine Anwendung zu erstellen:
npm install -g @vue/cli
oder
yarn global add @vue/cli
Um die Anwendung zu erstellen, verwenden Sie:
vue create [nazwa-projektu]
Dieser Befehl erstellt ein Projekt mit folgendem Verzeichnis- und Dateibaum:
├── babel.config.js
├── package.json
├── package-lock.json
├── public
│ ├── favicon.ico
│ └── index.html
├── README.md
└── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ └── HelloWorld.vue
└── main.js
Zu Erklärungszwecken konzentrieren wir uns in diesem Artikel nur auf vier Dateien, die sichtbare Auswirkungen auf unsere Anwendung haben (der Rest sind hauptsächlich Konfigurationsdateien, auf die wir hier nicht näher eingehen werden). Sie wurden leicht verändert, um ein angemessenes Vorgehen zu präsentieren. Es handelt sich um:
- public/index.html
- src/main.js
- src/App.vue
- src/components/HelloWorld.vue
public/index.html
Standardmäßig beginnt jede Webanwendung mit einer index.*-Datei – daran wurde nichts geändert. Das Einzige, worauf wir achten müssen, ist die Definition unseres Kern-DOM-Elements, das wir verwenden, um unsere Haupt-Vue-Instanz zu binden.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>my-awesome-project</title>
</head>
<body>
<noscript>
<strong>Entschuldigung, aber my-awesome-project funktioniert nicht richtig, ohne dass JavaScript aktiviert ist. Bitte aktivieren Sie es, um fortzufahren.</strong>
</noscript>
<div id="app"></div>
<!-- eingebundene Dateien werden automatisch injiziert -->
</body>
</html>
src/main.js
Ein Einstiegspunkt im Kontext der JavaScript-Logik. Hier passieren drei grundlegende Dinge, die es wert sind, betrachtet zu werden.
- Eine Vue-Instanz wird erstellt.
- Rendering der obersten Ebene der Komponente wird an App.vue verschoben.
- Die Vue-Instanz ist an das #app-Element in der index.html-Datei gebunden.
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
src/App.vue
Um zu verstehen, wie der Code dieser Datei funktioniert, müssen wir die Struktur von Single File Components diskutieren. Laut diesem Konzept muss, wie der Name schon sagt, jede Komponente in einer separaten Datei sein und die Endung *.vue besitzen. Lassen Sie uns das Beispiel unten betrachten.
<template>
<div id="app-container">
<hello-world message="Willkommen bei Ihrer Vue.js-App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
<style>
#app-container {
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Wir können drei Hauptelemente des Datei-Inhalts unterscheiden.
template
Komponentenvorlage. Hier setzen wir den Code ein, der bisher in der Template-Eigenschaft enthalten war.
script
Komponentenlogik. Wie Sie sehen, verwenden wir hier nicht Vue.component (dies ist die Definition einer globalen Komponente). Sie sollten beachten, dass Sie sich ohne vorheriges Importieren nicht darauf beziehen können. Zusätzlich muss der Name der importierten Komponente im Komponentenfeld des exportierten Objekts platziert werden, damit das Framework das Template richtig in echte HTML-Syntax umwandeln kann.
style
Komponentenbezogene Styles. Hier können Sie reines CSS verwenden oder einen der bekannten Präprozessoren: Sass, Less oder Stylus. Beim Erstellen einer Anwendung wird ein solcher Code in ein browserfreundliches CSS kompiliert.
src/HelloWorld.vue
Die zweite Single File Component in unserer Anwendung. Schauen Sie sich genauer an, wie Eigenschaften übergeben werden. App.vue enthält seine eigene message-Eigenschaft, die dann in die props-Tabelle in der Unterkomponente eingefügt wird. Der Scope-Tag im <style>-Tag lohnt eine nähere Betrachtung. Er stellt sicher, dass der Stil nur für diese Komponente angewendet wird. In Bezug auf das obige Beispiel bedeutet dies, dass Absätze nur in der HelloWorld-Komponente rot sein werden.
<template>
<div class="hello">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: ['message']
}
</script>
<style scoped>
p {
color: red;
}
</style>
Die nächste Entwicklungsstufe der Anwendung sieht gleich aus. Sie können komplexe Komponentenstrukturen erstellen, um das gewünschte Ergebnis in Form einer vollständigen und funktionalen Anwendung zu erzielen. Es gibt eine breite Palette von Bibliotheken und Add-ons, die für Vue erhältlich sind. Sie können Ihre Anwendung mit Routing (Vue-Router), Vuex (Redux-Äquivalent), bereits fertigen Komponenten aus CSS-Frameworks (z. B. Bootstrap, Foundation) sowie Bibliotheken (Lodash, Axios) und vielen anderen anreichern. Die Möglichkeiten sind nahezu endlos.
Was kommt als nächstes?
In diesem Artikel haben wir die Grundlagen des Erstellens einfacher Vue.js-Anwendungen vorgestellt. Wir haben die grundlegenden Mechanismen im Framework kennen gelernt. Wir wissen bereits, wie eine Vue-Instanz funktioniert, was Direktiven sind und wie wiederverwendbare Komponenten erstellt werden. Wir wissen auch, wie wir die Entwicklung von Anwendungen mit npm und vue-cli angehen können.
Allerdings ist das hier vorgestellte Wissen wirklich grundlegend, weshalb es sich lohnt, sich mit fortgeschritteneren Techniken vertraut zu machen (siehe „Empfohlene Quellen”). Es kann eine Reihe von Vorteilen bringen: Gute Kenntnisse eines der modernen JavaScript-Frameworks beschleunigen die Erstellung einer Client-Schicht, der Code ist besser organisiert und weniger fehleranfällig, was zu attraktiven und komplexen Frontend-Anwendungen führt.
Empfohlene Quellen
Eine Wissensschatz über Vue.js:
https://github.com/vuejs/awesome-vue
Eine kostenlose Tutorial-Serie, die diesen Artikel perfekt ergänzt:
https://laracasts.com/series/learn-vue-2-step-by-step
Kostenpflichtiger Kurs auf Udemy:
https://www.udemy.com/vuejs-2-the-complete-guide