Vue.js Workshop


Ruben Gees (Smartsquare GmbH)

Übersicht

  • Clientseitiges Javascript Framework zur Erstellung von Single-Page-Webanwendungen.
  • Entwickler: Evan You und Community auf Github.

Warum SPA?

  • Single-Page-Anwendungen sind schnell und erfordern kein erneutes Laden der Seite.
  • Schneller Entwicklungs-Start: Es wird kein Server benötigt, da alle Seiten statisch sind.
  • Bessere Trennung zwischen Frontend und Backend.
    • Frontend und Backend können separat voneinander deployed werden.
    • Schnittstelle vom Backend auch für andere Anwendungen nutzbar (bspw. Smartphone Apps).

Warum Vue?

  • Progressiv: Vue kann nach und nach adaptiert werden.
  • Einfach zu erlernen: Nur Vorwissen in JS und HTML nötig.
  • Mächtig: Das MVVM-Muster mit reaktivem Databinding erlaubt einfache Programmierung komplexer Abläufe.
  • Gibt keine Struktur der Anwendung vor.

Vue vs. React

  • Identische Performanz, beide verwenden Virtual DOM.
  • Manuelle Optimierung entfällt in Vue, da Änderungen automatisch erkannt werden.
  • Templates vs JSX.
  • Höhere Lernkurve bei React.

Vue vs Angular (2+)

  • Identische Performanz.
  • JavaScript vs TypeScript.
  • Angular selbst nach allen Optimierungen noch mehr als doppelt so groß.
  • Angular weniger Flexibel, gibt dafür aber mehr vor.
  • Höhere Lernkurve bei Angular.

Setup

<div id="app"></div>

<script src="https://unpkg.com/vue"></script>
<script>
var app = new Vue({
  el: '#app'
})
</script>
Oder
$ vue create my-project
(Später mehr)

Databinding
(One-Way)

<div id="app">
  {{ message }}
</div>
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
}
Ändert sich die message im Datenmodell von Vue, ändert sie sich auch im DOM.

Databinding
(Two-Way)

<div id="app">
  <p>{{ message }}</p>
  <input v-model="message">
</div>
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
Ändert sich die message im Input, ändert sie sich im Datenmodell (und umgekehrt).

Beispiel

{{ message }}

Conditionals

<div id="app">
  <span v-if="framework === 'vue'">Cool!</span>
  <span v-else>Lame :/</span>
</div>
var app = new Vue({
  el: '#app',
  data: {
    framework: 'vue'
  }
})
Das erste span wird nur zum DOM hinzugefügt, wenn die Bedingung erfüllt ist. Falls nicht, wird das andere Span hinzugefügt.

Loops

<div id="app">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
var app = new Vue({
  el: '#app',
  data: {
    todos: [
      { text: 'Write Code' },
      { text: 'Test Code' },
      { text: 'Deploy Code' }
    ]
  }
})
Für jedes Element in der Liste wird ein Element zum DOM hinzugefügt.

Components

<ol>
   <todo-item
     v-for="(todo, i) in todos"
     :todo="todo"
     :key="i">
   </todo-item>
 </ol>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app = new Vue({
  el: '#app',
  data: {
    todos: [
      { text: 'Write Code' },
      { text: 'Test Code' },
      { text: 'Deploy Code' }
    ]
  }
})

Components

Angelegte Components können direkt als HTML tags verwendet werden.

Mittels props können Daten übergeben werden (auch reaktiv!)

Beispiel

Die Vue Instanz

var app = new Vue({
  el: '#app',
  data: {
    someData: 1
  },
  computed: {
    doubleData: function () {
      return someData * 2;
    }
  }
  watch: {
    question: function (newSomething, oldSomething) {}
  },
  created: function () {},
  methods: {
    someMethod() {}
  }
})
Zur Umwandlung von Daten. Die Ergebnisse werden gecached und ändern sich, wenn sich einer der Abhängigkeiten ändert.

Die Vue Instanz

var app = new Vue({
  el: '#app',
  data: {
    someData: 1
  },
  computed: {
    doubleData: function () {
      return someData * 2;
    }
  },
  watch: {
    someData: function (newData, oldData) {}
  },
  created: function () {},
  methods: {
    someMethod() {}
  }
})
Zum Beobachten und manuellen Bearbeiten von Daten. Der Name entspricht dem Namen der Daten.

Die Vue Instanz

var app = new Vue({
  el: '#app',
  data: {
    someData: 1
  },
  computed: {
    doubleData: function () {
      return someData * 2;
    }
  },
  watch: {
    someData: function (newData, oldData) {}
  },
  created: function () {},
  methods: {
    someMethod() {}
  }
})
Lebenszyklus-Callback, welcher an bestimmter Stelle aufgerufen wird (alle Callbacks hier).

Die Vue Instanz

var app = new Vue({
  el: '#app',
  data: {
    someData: 1
  },
  computed: {
    doubleData: function () {
      return someData * 2;
    }
  },
  watch: {
    someData: function (newData, oldData) {}
  },
  created: function () {},
  methods: {
    someMethod() {}
  }
})
Frei definierbare Methoden die auch aus dem Template heraus aufgerufen werden können.

Single file components

  • Template, Component und CSS in einer Datei.
  • Tooling erlaubt Nutzung neuester JS & CSS Features, auch in älteren Browsern.
  • CommonJS Module für einfache imports und exports von Modulen.
  • Ab Projekten mittlerer Größe unverzichtbar.

Beispiel

<template>
  <div id="app">
    {{ message }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue!'
    }
  }
}
</script>

<style scoped>
.app {
  color: red;
}
</style>

Vue CLI

  • Generiert Boilerplate für neues Projekt mit Single File Components.
  • Weitere Features können dynamisch ausgewählt werden.

Installation

$ yarn global add @vue/cli

Neues Projekt

$ vue create project-name

Vue CLI

Let's code

Notizblock App mit bestehendem Backend
Ziel:

Let's Code

Projekt klonen: https://github.com/rubengees/vue-workshop

Backend starten:
$ cd backend
$ ./gradlew bootRun -Dserver.port=8000
Frontend starten:
$ cd frontend
$ yarn serve

Backend API

Methode Endpoint Beschreibung
POST /api/notes Legt eine neue Notiz an.
GET /api/notes Gibt alle Notizen zurück.
GET /api/notes/{id} Gibt eine spezifische Notiz zurück.

Backend API

Methode Endpoint Beschreibung
PUT /api/notes/{id} Aktualisiert eine spezifische Notiz.
DELETE /api/notes/{id} Löscht eine spezifische Notiz.