10. المثال [nuxt-07]: سياقات العميل والخادم
10.1. مقدمة
يهدف المثال [nuxt-07] إلى استكشاف كائن [context] على كل من جانب الخادم وجانب العميل. من المهم تذكر أن هذين المكونين لتطبيقات [nuxt] منفصلان: لا يشتركان في أي شيء باستثناء:
- ما يختار الخادم إرساله إلى العميل (في استجابة HTTP والصفحة المعروضة)؛
- ما يختار العميل إرساله إلى الخادم (في طلب HTTP الخاص به)؛
لذا، كما سنرى، في حين أن الكائنات التي يتعامل معها الخادم وتلك التي يتعامل معها العميل تحمل نفس الاسم، إلا أنها ليست متطابقة: فقد تكون أحيانًا نسخًا من بعضها البعض ولكنها لا تحمل أبدًا نفس المرجع. لا يؤثر تعديل كائن من جانب العميل على الكائن الذي يحمل نفس الاسم من جانب الخادم، والعكس صحيح.
يتم الحصول على المثال [nuxt-07] في البداية عن طريق نسخ المثال [nuxt-01]:

- في [2]، سنضيف مكونًا إضافيًا مشتركًا بين العميل والخادم؛
- في [3]، سنقوم بتعديل صفحة [index] بشكل طفيف؛
10.2. المكوّن الإضافي [common / main.js]
يتم تنفيذ المكون الإضافي [common / main.js] من قبل كل من العميل والخادم: ويرجع ذلك إلى التكوين التالي في [nuxt.config.js]:
/*
** Plugins to load before mounting the App
*/
plugins: [{ src: '~/plugins/common/main.js' }],
- السطر 4: عدم وجود الخاصية [mode] يعني أن المكون الإضافي [~/plugins/common/main.js] سيتم تنفيذه من قبل كل من العميل والخادم: الخادم أولاً، ثم العميل؛
سيكون هذا المكون الإضافي كما يلي:
/* 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))
}
}
- الأسطر 31–39: تُدرج الدالة [dumpkeys] خصائص الكائن الذي تم تمريره كمعلمة ثانية. تسبق هذه القائمة الرسالة التي تم تمريرها كمعلمة أولى؛
- السطر 3: نريد معرفة عدد الحجج التي تتلقاها الدالة. للقيام بذلك، نستخدم صيغة [...args]، التي ستضع معلمات الدالة الفعلية في المصفوفة [args]. سنجد أن هناك حجتين؛
- السطر 5: نعرض من يقوم بتنفيذ الكود، الخادم أم العميل؛
- السطر 6: منفذ الكود، العميل أو الخادم؛
- السطر 7: ثابت سلسلة يستخدم في السجلات؛
- السطر 12: سنرى أن الحجة الأولى التي يتلقاها المكون الإضافي هي سياق المنفذ؛
- السطر 14: قائمة مفاتيح كائن [context]؛
- السطر 16: سنرى أن كائن [context] يحتوي على خاصية [app] تمثل تطبيق [nuxt]؛
- السطر 18: سنرى أن الكائن [context] يحتوي على خاصية [route] تمثل المسار الحالي للموجه؛
- السطر 21: سنجد أن الكائن [app] يحتوي على خاصية [router] تمثل جهاز التوجيه؛
- السطر 23: يمثل الكائن [router.options.routes] المسارات المختلفة للتطبيق؛
- السطران 27-28: الحجة الثانية للمكوّن الإضافي هي الدالة [inject] التي استخدمناها في المثال [nuxt-06]؛
10.3. المكوّن الإضافي الذي ينفذه الخادم
عند التشغيل، يعرض الخادم ما يلي:
- السطران 11–12: سبق لنا أن استخدمنا الخصائص [base] و [env]، التي تأتي قيمها من ملف [nuxt.config.js]؛
- السطر 8: تشير الخاصية [app] إلى تطبيق [nuxt]؛
- السطر 18: تشير الخاصية [route] إلى المسار الحالي للموجه، أي الصفحة التي سيرسلها الخادم؛
- السطر 13: طلب HTTP من متصفح العميل؛
- السطر 14: استجابة HTTP من الخادم؛
قائمة خصائص [context.app] هي كما يلي:
- السطر 3: تتيح لنا الخاصية [router] الوصول إلى موجه التطبيق. وهذا أمر مهم في [Nuxt] لأن الموجه يتم تعريفه بواسطة [Nuxt] نفسها وليس بواسطة المطور. تتيح هذه الخاصية للمطور إمكانية تعديل الموجه؛
قائمة خصائص [context.route] هي كما يلي:
المسار [context.route] عند بدء تشغيل الخادم هو كما يلي:
- السطر 2: نرى أن الصفحة التالية على الخادم هي [index] وأن مسارها هو [/] (السطر 10)؛
- السطر 22: تسمح لك الخاصية [meta] بإضافة خصائص إلى المسارات؛
خصائص [context.app.router] الخاصة بالخادم هي كما يلي:
توجد المسارات المختلفة للتطبيق في الخاصية [context.app.router.options.routes]:
وأخيرًا، الحجة الثانية:
10.4. صفحة [index] الخاصة بالخادم
صفحة [index] هي كما يلي:
<!-- 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>
- السطر 43: لقد رأينا بالفعل أن سياق الصفحة يمكن العثور عليه في [this.$nuxt.context]؛
- السطر 42: نعرض أيضًا خصائص كائن [this.$nuxt]؛
عند تنفيذها بواسطة الخادم، تولد هذه الصفحة السجلات التالية:
خصائص سياق الخادم في صفحة [index] هي كما يلي:
هذه هي نفس الخصائص الموجودة في كائن [context] الخاص بالمكوّن الإضافي.
10.5. المكوّن الإضافي الذي يتم تنفيذه من قبل العميل
بمجرد أن يرسل الخادم صفحة [index] إلى متصفح العميل، تتولى البرامج النصية من جانب العميل زمام الأمور. سيتم بعد ذلك تنفيذ المكون الإضافي [main.js]. هذه السجلات هي كما يلي:
نجد خصائص مشابهة لتلك الموجودة على جانب الخادم، مع فقدان بعض الخصائص وظهور أخرى. على سبيل المثال، في السطر 4، الخصائص [req, res] —التي كانت طلبات HTTP لمتصفح العميل واستجابة HTTP للخادم— مفقودة.
10.6. صفحة [index] الخاصة بالعميل
تنتج صفحة [index] الخاصة بالعميل السجلات التالية:
- السطر 4: خصائص كائن [this.$nuxt]. إنه كائن غني يحتوي على 51 خاصية؛
- السطر 6: خصائص كائن [this.$nuxt.context]. هذه هي نفس الخصائص الموجودة في كائن [context] الخاص بمكوّن العميل الإضافي؛