11. Przykład [nuxt-08]: moduły pośredniczące routingu
W tym przykładzie wprowadzamy pojęcie modułów pośredniczących routingu, czyli skryptów uruchamianych przy każdej zmianie trasy.
Przykład [nuxt-08] uzyskano początkowo poprzez skopiowanie projektu [nuxt-01]:

Moduły pośredniczące routingu muszą znajdować się w folderze o nazwie [middleware] [2]. Możliwe jest zastosowanie routingu dwupoziomowego:
- routing stosowany przy każdej nawigacji. Jest on wówczas zadeklarowany w pliku [nuxt.config.js];
- routing stosowany do konkretnej strony, gdy jest ona celem routingu. Routing ten jest wówczas zadeklarowany na tej stronie docelowej;
11.1. Routing ogólny
Plik [middleware / routing.js] zapewni routing ogólny. Jest on przedmiotem następującej deklaracji w pliku [nuxt.config.js]:
router: {
base: '/nuxt-08/',
middleware: ['routing']
},
Middleware'y routingu ogólnego są właściwością routera (wiersz 1). Może istnieć wiele middleware'ów routingu. Dlatego w wierszu 3 wartość właściwości [middleware] jest tablicą. Widać, że do wskazania modułu pośredniczącego nie używa się ścieżki. Zostanie on automatycznie wyszukany w folderze [middleware] projektu;
Middleware [routing] służy tutaj wyłącznie do generowania logów:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// kto wykonuje ten kod?
console.log('[routing], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const routing = '[routing ' + who + ']'
// liczba argumentów
console.log(routing + ', il y a', args.length, 'argument(s)')
// pierwszy argument
const context = args[0]
// klucze kontekstu
dumpkeys(routing + ', context', context)
// aplikacja
dumpkeys(routing + ', context.app', context.app)
// trasa
dumpkeys(routing + ', context.route', context.route)
console.log(routing + ', context.route=', context.route)
// router
dumpkeys(routing + ', context.app.router', context.app.router)
// router.options.routes
dumpkeys(routing + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(routing + ', context.app.router.options.routes=', context.app.router.options.routes)
}
function dumpkeys(message, object) {
// lista kluczy [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// lista kluczy
if (object) {
console.log(Object.keys(object))
}
}
- wiersz 3: zobaczymy, że middleware otrzymuje argument: kontekst wykonawcy (serwer lub klient);
- wiersze 4–25: wyświetlamy właściwości różnych obiektów, aby sprawdzić, co można wykorzystać. Okazuje się, że kontekst oprogramowania pośredniczącego jest niemal identyczny z kontekstem wtyczki;
11.2. Przekierowanie do konkretnej strony
Chcemy kontrolować sposób, w jaki użytkownik trafia na stronę [index]. W tym celu musimy wprowadzić właściwość [middleware] na tej stronie [index]:
<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',
// używane komponenty
components: {
Layout,
Navigation
},
// cykl życia
beforeCreate() {
// klient i serwer
console.log('[home beforeCreate]')
},
created() {
// klient i serwer
console.log('[home created]')
},
beforeMount() {
// tylko klient
console.log('[home beforeMount]')
},
mounted() {
// tylko klient
console.log('[home mounted]')
},
// routing
middleware: ['index-routing']
}
</script>
- wiersz 34: właściwość [middleware] zawiera listę skryptów, które mają być wykonywane za każdym razem, gdy następną wyświetlaną stroną jest strona [index]. Również w tym przypadku skrypty te będą wyszukiwane w folderze [middleware] projektu;
Oprogramowanie pośredniczące [index-routing] ma następującą postać:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// kto wykonuje ten kod?
console.log('[index-routing], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const indexRouting = '[index-routing ' + who + ']'
// liczba argumentów
console.log(indexRouting + ', il y a', args.length, 'argument(s)')
// pierwszy argument
const context = args[0]
// klucze kontekstu
dumpkeys(indexRouting + ', context', context)
// aplikacja
dumpkeys(indexRouting + ', context.app', context.app)
// trasa
dumpkeys(indexRouting + ', context.route', context.route)
console.log(indexRouting + ', context.route=', context.route)
// router
dumpkeys(indexRouting + ', context.app.router', context.app.router)
// router.options.routes
dumpkeys(indexRouting + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(indexRouting + ', context.app.router.options.routes=', context.app.router.options.routes)
// skąd pochodzimy?
if (context.from) {
console.log('from=', context.from)
}
}
function dumpkeys(message, object) {
// lista kluczy dla [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// lista kluczy
if (object) {
console.log(Object.keys(object))
}
}
Kod [index-routing] jest identyczny z kodem [routing] i daje te same wyniki. Interesuje nas, kiedy te dwa moduły pośredniczące są uruchamiane.
11.3. Uruchomienie projektu
Uruchamiamy projekt. W tym momencie logi wyglądają następująco:
Serwer najpierw uruchamia skrypt [routing]:
Widzimy tu to samo, co uzyskaliśmy przy użyciu wtyczek.
- wiersz 15: właściwość [redirect] jest często wykorzystywana w oprogramowaniu pośredniczącym (middleware): pozwala ona zmienić cel bieżącego routingu;
Następnie, ponieważ strona, która ma zostać wyświetlona, to strona [index], serwer uruchamia skrypt [index-routing] i wyświetla następujące logi:
Wyniki uzyskane przy użyciu skryptu [index-routing] są analogiczne do tych uzyskanych przy użyciu skryptu [routing].
Po odebraniu strony [index] przez przeglądarkę klienta kontrolę przejmują skrypty klienckie. Logi przyjmują następujący wygląd:
Widać zatem, że podczas uruchamiania aplikacji klient nie uruchamia żadnego oprogramowania pośredniczącego. Oznacza to, że sytuacja ta będzie miała miejsce za każdym razem, gdy użytkownik wymusi wywołanie serwera. Oprogramowanie pośredniczące jest uruchamiane przez klienta wyłącznie podczas nawigacji w obrębie klienta. Przejdźmy na przykład do strony [page1] (jesteśmy na stronie [index]) za pomocą linku [Page 1]. Logi wyglądają wtedy następująco:
- wiersz 2: oprogramowanie pośredniczące [routing] jest uruchamiane przez klienta;
- wiersz 4: zwróć uwagę na właściwość [from]: jest to trasa, z której pochodzimy;
- wiersz 9: [context.route] to trasa docelowa;
- wiersze 15–18: wyświetlenie strony [page1];
Teraz wróćmy do strony [index] za pomocą linku [Home]. Logi wyglądają wówczas następująco:
- wiersze 1–15: klient uruchamia oprogramowanie pośredniczące [routing]. Jest to normalne zachowanie. Jest ono uruchamiane przy każdej zmianie trasy;
- wiersze 16–29: klient uruchamia oprogramowanie pośredniczące [index-routing], ponieważ:
- [index] jest celem bieżącej trasy (patrz wiersz 23);
- strona [index] zdefiniowała moduł pośredniczący o nazwie [index-routing];
Widać zatem, że moduły pośredniczące routingu ogólnego są uruchamiane przez klienta przed modułami pośredniczącymi przypisanymi do stron.