10. Esempio [nuxt-07]: Contesti client e server
10.1. Introduzione
L'esempio [nuxt-07] mira a esplorare l'oggetto [context] sia sul lato server che sul lato client. È importante ricordare che questi due componenti delle applicazioni [nuxt] sono separati: non condividono nulla tranne:
- ciò che il server sceglie di inviare al client (nella risposta HTTP e nella pagina renderizzata);
- ciò che il client sceglie di inviare al server (nella sua richiesta HTTP);
Quindi, come vedremo, sebbene gli oggetti gestiti dal server e quelli gestiti dal client abbiano lo stesso nome, non sono identici: a volte possono essere copie l'uno dell'altro, ma non hanno mai lo stesso riferimento. La modifica di un oggetto lato client non ha alcun effetto sull'oggetto con lo stesso nome sul lato server, e viceversa.
L'esempio [nuxt-07] si ottiene inizialmente copiando l'esempio [nuxt-01]:

- in [2], aggiungeremo un plugin condiviso dal client e dal server;
- in [3], modificheremo leggermente la pagina [index];
10.2. Il plugin [common / main.js]
Il plugin [common / main.js] viene eseguito sia dal client che dal server: ciò è dovuto alla seguente configurazione in [nuxt.config.js]:
/*
** Plugins to load before mounting the App
*/
plugins: [{ src: '~/plugins/common/main.js' }],
- riga 4: l'assenza della proprietà [mode] significa che il plugin [~/plugins/common/main.js] verrà eseguito sia dal client che dal server: prima dal server, poi dal client;
Questo plugin sarà il seguente:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// who executes this code?
console.log('[main server], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const main = '[main ' + who + ']'
// number of arguments
console.log(main + ', il y a', args.length, 'arguments')
// 1st argument
const context = args[0]
// key context
dumpkeys(main + ', context', context)
// the application
dumpkeys(main + ', context.app', context.app)
// the road
dumpkeys(main + ', context.route', context.route)
console.log(main + ', context.route=', context.route)
// the router
dumpkeys(main + ', context.app.router', context.app.router)
// on router.options.routes
dumpkeys(main + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(main + ', context.app.router.options.routes=', context.app.router.options.routes)
// 2nd argument
const inject = args[1]
console.log('inject=', typeof inject)
}
function dumpkeys(message, object) {
// list of [object] keys
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// kEY LIST
if (object) {
console.log(Object.keys(object))
}
}
- righe 31–39: la funzione [dumpkeys] elenca le proprietà dell'oggetto passato come secondo parametro. Questo elenco è preceduto dal messaggio passato come primo parametro;
- riga 3: vogliamo sapere quanti argomenti riceve la funzione. Per farlo, usiamo la notazione [...args], che inserirà i parametri effettivi della funzione nell'array [args]. Scopriremo che ci sono due argomenti;
- riga 5: visualizziamo chi sta eseguendo il codice, il server o il client;
- riga 6: l'esecutore del codice, client o server;
- riga 7: una costante stringa utilizzata nei log;
- riga 12: vedremo che il primo argomento ricevuto dal plugin è il contesto dell'esecutore;
- riga 14: elenco delle chiavi per l'oggetto [context];
- riga 16: vedremo che l'oggetto [context] ha una proprietà [app] che rappresenta l'applicazione [nuxt];
- riga 18: vedremo che l'oggetto [context] ha una proprietà [route] che rappresenta il percorso corrente del router;
- riga 21: vedremo che l'oggetto [app] ha una proprietà [router] che rappresenta il router;
- riga 23: l'oggetto [router.options.routes] rappresenta i vari percorsi dell'applicazione;
- righe 27–28: il secondo argomento del plugin è la funzione [inject] che abbiamo usato nell'esempio [nuxt-06];
10.3. Il plugin eseguito dal server
Una volta eseguito, il server visualizza quanto segue:
- righe 11–12: abbiamo già avuto modo di utilizzare le proprietà [base] e [env], i cui valori provengono dal file [nuxt.config.js];
- riga 8: la proprietà [app] si riferisce all'applicazione [nuxt];
- riga 18: la proprietà [route] si riferisce al percorso corrente del router, ovvero alla pagina che il server invierà;
- riga 13: la richiesta HTTP proveniente dal browser del client;
- riga 14: la risposta HTTP del server;
L'elenco delle proprietà [context.app] è il seguente:
- riga 3: la proprietà [router] ci consente di accedere al router dell'applicazione. Questo è importante in [Nuxt] poiché il router è definito da [Nuxt] stesso e non dallo sviluppatore. Questa proprietà consente allo sviluppatore di modificare il router;
L'elenco delle proprietà [context.route] è il seguente:
Il percorso [context.route] all'avvio del server è il seguente:
- riga 2: vediamo che la pagina successiva sul server è [index] e che il suo percorso è [/] (riga 10);
- riga 22: la proprietà [meta] consente di aggiungere proprietà ai percorsi;
Le proprietà di [context.app.router] del server sono le seguenti:
I vari percorsi dell'applicazione si trovano nella proprietà [context.app.router.options.routes]:
Infine, il secondo argomento:
10.4. La pagina [index] del server
La pagina [index] è la seguente:
<!-- page principale -->
<template>
<Layout :left="true" :right="true">
<!-- navigation -->
<Navigation slot="left" />
<!-- message-->
<b-alert slot="right" show variant="warning">
Home
</b-alert>
</Layout>
</template>
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
import Navigation from '@/components/navigation'
import Layout from '@/components/layout'
export default {
name: 'Home',
// components used
components: {
Layout,
Navigation
},
data() {
return {
who: process.server ? 'server' : 'client'
}
},
// life cycle
beforeCreate() {
// client and server
console.log('[home beforeCreate]')
},
created() {
// client and server
console.log('[home ' + this.who + ' created]')
this.dumpkeys('[home ' + this.who + ' created], this.$nuxt', this.$nuxt)
this.dumpkeys('[home ' + this.who + ' created], this.$nuxt.context', this.$nuxt.context)
},
beforeMount() {
// customer only
console.log('[home ' + this.who + ' beforeMount]')
},
mounted() {
// customer only
console.log('[home ' + this.who + ' mounted]')
},
methods: {
dumpkeys(message, object) {
// list of [object] keys
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
if (object) {
console.log(Object.keys(object))
}
}
}
}
</script>
- riga 43: abbiamo già visto che il contesto di una pagina si trova in [this.$nuxt.context];
- riga 42: visualizziamo anche le proprietà dell'oggetto [this.$nuxt];
Quando viene eseguita dal server, questa pagina genera i seguenti log:
Le proprietà del contesto del server nella pagina [index] sono le seguenti:
Queste sono le stesse proprietà presenti nell'oggetto [context] del plugin.
10.5. Il plugin eseguito dal client
Una volta che il server ha inviato la pagina [index] al browser del client, subentrano gli script lato client. Verrà quindi eseguito il plugin [main.js]. Questi log sono i seguenti:
Troviamo proprietà simili a quelle presenti sul lato server, con alcune proprietà mancanti e altre presenti. Ad esempio, alla riga 4, mancano le proprietà [req, res] — che erano le richieste HTTP del browser client e la risposta HTTP del server.
10.6. La pagina [index] del client
La pagina [index] del client produce i seguenti log:
- riga 4: le proprietà dell'oggetto [this.$nuxt]. Si tratta di un oggetto ricco con 51 proprietà;
- riga 6: le proprietà dell'oggetto [this.$nuxt.context]. Si tratta delle stesse proprietà presenti nell'oggetto [context] del plugin client;