6. Приклад [nuxt-03]: nuxtServerInit
Проєкт [nuxt-03] має на меті продемонструвати функцію сховища [Vuex] під назвою [nuxtServerInit]. Вона дозволяє серверу ініціалізувати сховище [Vuex] так само, як це робить функція [fetch]. Однак, на відміну від функції [fetch], функція [nuxtServerInit] ніколи не виконується клієнтом.

Проєкт [nuxt-03] спочатку створюється шляхом копіювання проєкту [nuxt-01], з якого видаляється сторінка [page2] з папки [pages] та з компонента [navigation]. Папка [store] створюється шляхом копіювання папки [nuxt-02/store].
6.1. Штора [Vuex]
Файл [Vuex] буде реалізовано за допомогою наступного файлу [store/index.js]:
/* eslint-disable no-console */
export const state = () => ({
// лічильник
counter: 0
})
export const mutations = {
// збільшення лічильника на одиницю [inc]
increment(state, inc) {
state.counter += inc
}
}
export const actions = {
async nuxtServerInit(store, context) {
// хто виконує цей код?
console.log('nuxtServerInit, client=', process.client, 'serveur=', process.server)
// очікуємо завершення обіцянки
await new Promise(function(resolve, reject) {
// зазвичай тут використовується асинхронна функція
// її імітують за допомогою очікування протягом однієї секунди
setTimeout(() => {
// успіх
resolve()
}, 1000)
})
// змінюємо значення в змінній
store.commit('increment', 34)
// журнал
console.log('nuxtServerInit commit terminé')
}
}
- рядки 1–12: аналогічні тим, що були в проєкті [nuxt-02];
- рядки 14–32: експортується об’єкт [actions]. Це зарезервований термін сховища [Vuex];
- рядок 15: визначається функція [nuxtServerInit]. Вона буде виконана сервером під час запуску додатка. Зазвичай її завданням є ініціалізація сховища [Vuex] за допомогою зовнішніх даних, отриманих за допомогою асинхронної функції. [nuxt] очікує, поки ця функція поверне результати, перш ніж розпочати життєвий цикл запитуваної сторінки. Функція отримує два параметри:
- сховище [Vuex], яке потрібно ініціалізувати;
- поточний контекст [nuxt];
- рядки 19–26: очікування завершення асинхронної дії, у даному випадку штучне очікування протягом однієї секунди (рядок 15);
- рядок 28: лічильнику присвоюється значення 34;
- рядки 17 і 30: записи в журналі для відстеження ходу виконання функції [nuxtServerInit];
6.2. Сторінка [index]
Сторінка [index] матиме такий вигляд:
<!-- сторінка [index] -->
<template>
<Layout :left="true" :right="true">
<!-- навігація -->
<Navigation slot="left" />
<!-- повідомлення-->
<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: {
Layout,
Navigation
},
data() {
return {
value: 0
}
},
// життєвий цикл
beforeCreate() {
// клієнт і сервер
console.log('[home beforeCreate]')
},
created() {
// клієнт і сервер
this.value = this.$store.state.counter
console.log('[home created], value=', this.value)
},
beforeMount() {
// тільки клієнт
console.log('[home beforeMount]')
},
mounted() {
// тільки клієнт
console.log('[home mounted]')
}
}
</script>
- рядок 37: значення лічильника, ініціалізованого функцією [nuxtServerInit], присвоюється властивості [value] з рядка 27. Це значення відображається у рядку 7;
- рядок 37 буде виконано як сервером, так і клієнтом. В обох випадках властивість [value] отримає однакове значення, що забезпечує ідентичність сторінки, згенерованої сервером, та сторінки, згенерованої клієнтом;
6.3. Сторінка [page1]
Сторінка [page1] отримується шляхом копіювання сторінки [index]. Потім її текст змінюють, замінивши [home] на [page1]:
<!-- сторінка [page1]] -->
<template>
<Layout :left="true" :right="true">
<!-- навігація -->
<Navigation slot="left" />
<!-- повідомлення-->
<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: {
Layout,
Navigation
},
data() {
return {
value: 0
}
},
// життєвий цикл
beforeCreate() {
// клієнт і сервер
console.log('[page1 beforeCreate]')
},
created() {
// клієнт і сервер
this.value = this.$store.state.counter
console.log('[page1 created], value=', this.value)
},
beforeMount() {
// тільки клієнт
console.log('[page1 beforeMount]')
},
mounted() {
// тільки клієнт
console.log('[page1 mounted]')
}
}
</script>
Ця сторінка призначена виключно для забезпечення навігації між двома сторінками.
6.4. Exécution
Файл [nuxt.config.js] змінюється наступним чином:
// каталог вихідного коду
srcDir: 'nuxt-03',
// маршрутизатор
router: {
// кореневий каталог URL додатка
base: '/nuxt-03/'
},
// сервер
server: {
// порт служби, за замовчуванням 3000
port: 81,
// мережеві адреси, на яких відбувається прослуховування, за замовчуванням localhost: 127.0.0.1
// 0.0.0.0 = усі мережеві адреси комп’ютера
host: 'localhost'
}
Сторінка, що відображається під час виконання, має такий вигляд:

- У файлі [5] видно, що функція [nuxtServerInit] була виконана сервером до завершення життєвого циклу сторінки [index]. [nuxt] дочекалася завершення роботи асинхронної функції, перш ніж перейти до життєвого циклу;
- у [4] видно, що клієнт не виконав функцію [nuxtServerInit];
Тепер перейдемо двічі: index --> page1 --> index. Журнали виглядають так:

- у [1-2] видно, що функція [nuxtServerInit] не виконується клієнтом;
Тепер введемо URL зі сторінки [page1] вручну, щоб примусово викликати сервер:

у [3-4] ми бачимо той самий механізм, що й перед завантаженням сторінки [index] під час запуску. Нагадаємо те, про що вже йшлося: коли ми примусово викликаємо сторінку на сервері, все відбувається так, ніби додаток перезапускається зі стартовою сторінкою, якою є запитувана сторінка;