Skip to content

6. Beispiel [nuxt-03]: nuxtServerInit

Das Projekt [nuxt-03] soll eine [Vuex]-Store-Funktion namens [nuxtServerInit] demonstrieren. Sie ermöglicht es dem Server, den [Vuex]-Store zu initialisieren, genau wie es die [fetch]-Funktion tut. Im Gegensatz zur [fetch]-Funktion wird die [nuxtServerInit]-Funktion jedoch niemals vom Client ausgeführt.

Image

Das Projekt [nuxt-03] wird zunächst durch Klonen des Projekts [nuxt-01] erstellt, aus dem die Seite [page2] im Ordner [pages] und die Komponente [navigation] entfernt werden. Der Ordner [store] wird durch Klonen des Ordners [nuxt-02/store] erstellt.

6.1. Der [Vuex]-Store

Der [Vuex]-Store wird durch die folgende Datei [store/index.js] implementiert:


/* eslint-disable no-console */
export const state = () => ({
  // meter
  counter: 0
})
 
export const mutations = {
  // increment counter by one [inc] value
  increment(state, inc) {
    state.counter += inc
  }
}
 
export const actions = {
  async nuxtServerInit(store, context) {
    // who executes this code?
    console.log('nuxtServerInit, client=', process.client, 'serveur=', process.server)
    // waiting for a promise to be fulfilled
    await new Promise(function(resolve, reject) {
      // this is normally an asynchronous function
      // we simulate it with a one-second wait
      setTimeout(() => {
        // success
        resolve()
      }, 1000)
    })
    // modify the blind
    store.commit('increment', 34)
    // log
    console.log('nuxtServerInit commit terminé')
  }
}
  • Zeilen 1–12: entsprechen denen im Projekt [nuxt-02];
  • Zeilen 14–32: Wir exportieren ein [actions]-Objekt. Dies ist ein reservierter Begriff im [Vuex]-Store;
  • Zeile 15: Wir definieren die Funktion [nuxtServerInit]. Diese wird vom Server ausgeführt, wenn die Anwendung startet. Ihre übliche Aufgabe ist es, einen [Vuex]-Store mithilfe externer Daten zu initialisieren, die über eine asynchrone Funktion abgerufen werden. [nuxt] wartet darauf, dass diese Funktion ihre Ergebnisse zurückgibt, bevor der Lebenszyklus der angeforderten Seite beginnt. Die Funktion benötigt zwei Parameter:
    • den zu initialisierenden [Vuex]-Store;
    • den aktuellen [Nuxt]-Kontext;
  • Zeilen 19–26: Wir warten darauf, dass die asynchrone Aktion abgeschlossen wird, hier eine künstliche Wartezeit von einer Sekunde (Zeile 15);
  • Zeile 28: Der Zähler wird auf 34 gesetzt;
  • Zeilen 17 und 30: Logs zur Verfolgung der Ausführung der [nuxtServerInit]-Funktion;

6.2. Die [index]-Seite

Die [index]-Seite sieht wie folgt aus:


<!-- page [index] -->
<template>
  <Layout :left="true" :right="true">
    <!-- navigation -->
    <Navigation slot="left" />
    <!-- message-->
    <b-alert slot="right" show variant="warning"> Home - value= {{ value }} </b-alert>
  </Layout>
</template>
 
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
 
import Layout from '@/components/layout'
import Navigation from '@/components/navigation'
export default {
  name: 'Home',
  // components used
  components: {
    Layout,
    Navigation
  },
  data() {
    return {
      value: 0
    }
  },
  // life cycle
  beforeCreate() {
    // client and server
    console.log('[home beforeCreate]')
  },
  created() {
    // client and server
    this.value = this.$store.state.counter
    console.log('[home created], value=', this.value)
  },
  beforeMount() {
    // customer only
    console.log('[home beforeMount]')
  },
  mounted() {
    // customer only
    console.log('[home mounted]')
  }
}
</script>
  • Zeile 37: Der Wert des durch die Funktion [nuxtServerInit] initialisierten Zählers wird der Eigenschaft [value] in Zeile 27 zugewiesen. Dieser Wert wird in Zeile 7 angezeigt;
  • Zeile 37 wird sowohl vom Server als auch vom Client ausgeführt. In beiden Fällen erhält die Eigenschaft [value] denselben Wert, wodurch sichergestellt wird, dass die vom Server generierte Seite mit der vom Client generierten übereinstimmt;

6.3. Die Seite [page1]

Die Seite [page1] wird durch Kopieren der Seite [index] erstellt. Anschließend ändern wir den Text so, dass [home] durch [page1] ersetzt wird:


<!-- page [page1]] -->
<template>
  <Layout :left="true" :right="true">
    <!-- navigation -->
    <Navigation slot="left" />
    <!-- message-->
    <b-alert slot="right" show variant="warning"> Page1 - value= {{ value }} </b-alert>
  </Layout>
</template>
 
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
 
import Layout from '@/components/layout'
import Navigation from '@/components/navigation'
 
export default {
  name: 'Page1',
  // components used
  components: {
    Layout,
    Navigation
  },
  data() {
    return {
      value: 0
    }
  },
  // life cycle
  beforeCreate() {
    // client and server
    console.log('[page1 beforeCreate]')
  },
  created() {
    // client and server
    this.value = this.$store.state.counter
    console.log('[page1 created], value=', this.value)
  },
  beforeMount() {
    // customer only
    console.log('[page1 beforeMount]')
  },
  mounted() {
    // customer only
    console.log('[page1 mounted]')
  }
}
</script>

Diese Seite dient lediglich der Navigation zwischen zwei Seiten.

6.4. Ausführung

Die Datei [nuxt.config.js] wird wie folgt geändert:


// source code directory
  srcDir: 'nuxt-03',
  // router
  router: {
    // application URL root
    base: '/nuxt-03/'
  },
  // server
  server: {
    // service port, default 3000
    port: 81,
    // network addresses listened to, default localhost: 127.0.0.1
    // 0.0.0.0 = all the machine's network addresses
    host: 'localhost'
}

Die bei der Ausführung angezeigte Seite sieht dann wie folgt aus:

Image

  • In [5] sehen wir, dass die Funktion [nuxtServerInit] vom Server vor dem Lebenszyklus der Seite [index] ausgeführt wurde. [nuxt] wartete, bis die asynchrone Funktion ihre Arbeit beendet hatte, bevor es mit dem Lebenszyklus fortfuhr;
  • In [4] sehen wir, dass der Client die Funktion [nuxtServerInit] nicht ausgeführt hat;

Navigieren wir nun zweimal: index --> page1 --> index. Die Protokolle sehen dann wie folgt aus:

Image

  • In [1-2] sehen wir, dass die Funktion [nuxtServerInit] vom Client nicht ausgeführt wird;

Geben wir nun manuell die URL für die Seite [page1] ein, um einen Aufruf an den Server zu erzwingen:

Image

In [3-4] sehen wir denselben Mechanismus, der dem Laden der Seite [index] beim Start vorausging. Fassen wir zusammen, was zuvor erwähnt wurde: Wenn wir eine Seite dazu zwingen, den Server aufzurufen, ist es, als würde die Anwendung mit einer Startseite neu starten, die der angeforderten Seite entspricht;