Skip to content

6. مثال [nuxt-03]: nuxtServerInit

يهدف مشروع [nuxt-03] إلى تقديم وظيفة من متجر [Vuex] تسمى [nuxtServerInit]. وهي تسمح للخادم بتهيئة المخزن [Vuex] كما تفعل الوظيفة [fetch]. ولكن على عكس الوظيفة [fetch]، لا يتم تنفيذ الوظيفة [nuxtServerInit] أبدًا من قبل العميل.

Image

يتم الحصول على المشروع [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'
}

الصفحة المعروضة عند التنفيذ هي التالية:

Image

  • في [5]، نرى أن الدالة [nuxtServerInit] قد تم تنفيذها بواسطة الخادم قبل دورة حياة الصفحة [index]. انتظرت [nuxt] حتى انتهت الوظيفة غير المتزامنة من عملها قبل الانتقال إلى دورة الحياة؛
  • في [4]، نرى أن العميل لم ينفذ الوظيفة [nuxtServerInit

الآن دعونا نتنقل مرتين: index --> page1 --> index. تكون السجلات عندئذٍ كما يلي:

Image

  • في [1-2]، نرى أن الوظيفة [nuxtServerInit] لم يتم تنفيذها من قبل العميل؛

الآن، لنكتب URL من الصفحة [page1] يدويًا لإجبار الخادم على الاستجابة:

Image

في [3-4]، نجد نفس الآلية التي سبقت تحميل الصفحة [index] عند بدء التشغيل. نذكر هنا ما سبق ذكره: عند فرض استدعاء صفحة إلى الخادم، يحدث كل شيء كما لو أن التطبيق أعيد تشغيله بصفحة رئيسية هي الصفحة المطلوبة؛