Skip to content

10. مثال [nuxt-07]: زمینه‌های کلاینت و سرور

10.1. Présentation

مثال [nuxt-07] با هدف بررسی شیء [context] از دیدگاه‌های سمت سرور و سمت کلاینت ارائه شده است. مهم است به خاطر داشته باشید که این دو مؤلفه از برنامه‌های [nuxt] از یکدیگر مستقل هستند: آنها به جز موارد زیر هیچ چیز مشترکی ندارند:

  • آنچه سرور انتخاب می‌کند تا به کلاینت ارسال کند (در پاسخ HTTP و صفحه ارسال‌شده)؛
  • آنچه کلاینت انتخاب می‌کند به سرور ارسال کند (در درخواست HTTP خود)؛

بنابراین، همانطور که خواهیم دید، اگرچه اشیایی که توسط سرور و اشیایی که توسط کلاینت پردازش می‌شوند نام یکسانی دارند، اما یکسان نیستند: آنها ممکن است گاهی کپی یکدیگر باشند اما هرگز مرجع یکسانی ندارند. تغییر یک شیء در سمت کلاینت هیچ تأثیری بر شیء با نام مشابه در سمت سرور ندارد، و بالعکس.

مثال [nuxt-07] در ابتدا با کپی کردن مثال [nuxt-01] به دست می‌آید:

Image

  • به [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' }],
  • خط ۴: عدم وجود ویژگی [mode] به این معنی است که پلاگین [~/plugins/common/main.js] هم توسط کلاینت و هم توسط سرور اجرا خواهد شد: ابتدا سرور، سپس کلاینت؛

این افزونه به شرح زیر خواهد بود:


/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
  // چه کسی این کد را اجرا می‌کند؟
  console.log('[main server], process.server=', process.server, 'process.client=', process.client)
  const who = process.server ? 'server' : 'client'
  const main = '[main ' + who + ']'
  // تعداد آرگومان‌ها
  console.log(main + ', il y a', args.length, 'arguments')

  // آرگومان اول
  const context = args[0]
  // کلیدهای زمینه
  dumpkeys(main + ', context', context)
  // برنامه
  dumpkeys(main + ', context.app', context.app)
  //مسیر
  dumpkeys(main + ', context.route', context.route)
  console.log(main + ', context.route=', context.route)
  // روتر
  dumpkeys(main + ', context.app.router', context.app.router)
  // 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)

  // آرگومان دوم
  const inject = args[1]
  console.log('inject=', typeof inject)
}

function dumpkeys(message, object) {
  // فهرست کلیدها برای [object]
  const ligne = 'Liste des clés [' + message + ']'
  console.log(ligne)
  // فهرست کلیدها
  if (object) {
    console.log(Object.keys(object))
  }
}
  • خطوط ۳۱–۳۹: تابع [dumpkeys] ویژگی‌های شیء ارسال‌شده به‌عنوان پارامتر دوم را فهرست می‌کند. این لیست با پیامی که به‌عنوان پارامتر اول ارسال شده است، پیش‌فرض می‌شود؛
  • خط ۳: ما می‌خواهیم بدانیم این تابع چند آرگومان دریافت می‌کند. برای این کار، از نشانه [...args] استفاده می‌کنیم که پارامترهای واقعی تابع را در آرایه [args] قرار می‌دهد. خواهیم دید که دو آرگومان وجود دارد؛
  • خط ۵: نمایش می‌دهیم که چه کسی کد را اجرا می‌کند – سرور یا کلاینت؛
  • خط ۶: عاملی که کد را اجرا می‌کند، کلاینت یا سرور؛
  • خط ۷: یک مقدار ثابت رشته‌ای که در لاگ‌ها استفاده می‌شود؛
  • خط ۱۲: می‌بینیم که اولین آرگومان دریافتی توسط پلاگین، زمینهٔ اجراکننده است؛
  • خط ۱۴: فهرستی از کلیدهای شیء [context];
  • خط 16: خواهیم دید که شی [context] دارای خاصیتی به نام [app] است که نمایانگر برنامه [nuxt] می‌باشد؛
  • خط ۱۸: خواهیم دید که شیء [context] دارای خاصیتی به نام [route] است که مسیر فعلی روتر را نشان می‌دهد؛
  • خط ۲۱: خواهیم دید که شیء [app] دارای خاصیتی به نام [router] است که نماینده روتر می‌باشد؛
  • خط ۲۳: شیء [router.options.routes] نمایانگر مسیرهای مختلف در برنامه است؛
  • خطوط ۲۷–۲۸: آرگومان دوم پلاگین، تابع [inject] است که در مثال [nuxt-06] استفاده کردیم؛

10.3. پلاگینی که توسط سرور اجرا می‌شود

پس از اجرا، سرور موارد زیر را نمایش می‌دهد:

[main server], process.server= true process.client= false
[main server], il y a 2 arguments
Liste des clés [[main server], context]
[
  'isStatic',
  'isDev',
  'isHMR',
  'app',
  'payload',
  'error',
  'base',
  'env',
  'req',
  'res',
  'ssrContext',
  'redirect',
  'beforeNuxtRender',
  'route',
  'next',
  '_redirected',
  '_errored',
  'params',
  'query',
   '$axios'
]
  • خطوط ۱۱–۱۲: ما قبلاً از ویژگی‌های [base] و [env] استفاده کرده‌ایم که مقادیرشان از فایل [nuxt.config.js] گرفته می‌شود؛
  • خط ۸: ویژگی [app] به برنامه [nuxt] اشاره دارد؛
  • خط ۱۸: ویژگی [route] به مسیر فعلی روتر اشاره دارد، یعنی صفحه‌ای که سرور ارسال خواهد کرد؛
  • خط ۱۳: درخواست مرورگر کلاینت HTTP;
  • خط 14: پاسخ سرور HTTP;

فهرست ویژگی‌ها برای [context.app] به شرح زیر است:

Liste des clés [[main server], context.app]
[
  'router',
  'nuxt',
  'head',
  'render',
  'data',
  'beforeCreate',
  'created',
  'mounted',
  'watch',
  'computed',
  'methods',
  'components',
  'context',
   '$axios'
]
  • خط ۳: ویژگی [router] دسترسی ما را به روتر برنامه فراهم می‌کند. این موضوع در [nuxt] اهمیت دارد، زیرا روتر توسط خود [nuxt] تعریف می‌شود و نه توسط توسعه‌دهنده. این ویژگی به توسعه‌دهنده اجازه می‌دهد روتر را تغییر دهد؛

فهرست ویژگی‌های [context.route] به شرح زیر است:

Liste des clés [[main server], context.route]
[
  'name',
  'meta',
  'path',
  'hash',
  'query',
  'params',
  'fullPath',
   'مطابقت داده شده'
]

مسیر [context.route] در هنگام راه‌اندازی سرور به شرح زیر است:

[main server], context.route= {
  name: 'index',
  meta: [
    {}
  ],
  path: '/',
  hash: '',
  query: {},
  params: {},
  fullPath: '/',
  matched: [
    {
      path: '',
      regex: /^(?:\/(?=$))?$/i,
      components: [Object],
      instances: {},
      name: 'index',
      parent: undefined,
      matchAs: undefined,
      redirect: undefined,
      beforeEnter: undefined,
      meta: {},
      props: {}
    }
  ]
}
  • خط ۲: می‌بینیم که صفحه بعدی روی سرور [index] است و مسیر آن [/] (خط ۱۰) است؛
  • خط ۲۲: ویژگی [meta] امکان افزودن ویژگی‌ها به مسیرها را فراهم می‌کند؛

ویژگی‌های روتر [context.app.router] سرور به شرح زیر است:

Liste des clés [[main server], context.app.router]
[
  'app',
  'apps',
  'options',
  'beforeHooks',
  'resolveHooks',
  'afterHooks',
  'matcher',
  'fallback',
  'mode',
   'تاریخچه'
]

مسیرهای مختلف برنامه در خصوصیت [context.app.router.options.routes] یافت می‌شوند:

Liste des clés [[main server], context.app.router.options.routes]
[
  '0',
  '1',
  '2'
]
[main server], context.app.router.options.routes= [
  {
    path: '/page1',
    component: [Function: _d7b6c762],
    name: 'page1'
  },
  {
    path: '/page2',
    component: [Function: _d79a9860],
    name: 'page2'
  },
  {
    path: '/',
    component: [Function: _31eaad9f],
    name: 'index'
  }
]

در نهایت، آرگومان دوم:

inject= function

10.4. صفحه [index] روی سرور

صفحه [index] به شرح زیر است:


<!-- صفحه اصلی -->
<template>
  <Layout :left="true" :right="true">
    <!-- ناوبری -->
    <Navigation slot="left" />
    <!-- پیام-->
    <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: {
    Layout,
    Navigation
  },
  data() {
    return {
      who: process.server ? 'server' : 'client'
    }
  },

  //چرخهٔ زندگی
  beforeCreate() {
    // کلاینت و سرور
    console.log('[home beforeCreate]')
  },
  created() {
    // کلاینت و سرور
    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() {
    //فقط کلاینت
    console.log('[home ' + this.who + ' beforeMount]')
  },
  mounted() {
    // فقط کلاینت
    console.log('[home ' + this.who + ' mounted]')
  },
  methods: {
    dumpkeys(message, object) {
      // فهرست کلیدها برای [object]
      const ligne = 'Liste des clés [' + message + ']'
      console.log(ligne)
      if (object) {
        console.log(Object.keys(object))
      }
    }
  }
}
</script>
  • خط ۴۳: ما قبلاً دیده‌ایم که زمینه یک صفحه را می‌توان در [this.$nuxt.context] یافت؛
  • خط ۴۲: ویژگی‌های شیء [this.$nuxt] نیز نمایش داده می‌شوند؛

هنگامی که این صفحه توسط سرور اجرا می‌شود، لاگ‌های زیر تولید می‌شوند:

[home beforeCreate]
[home server created]
Liste des clés [[home server created], this.$nuxt]
[
  '_uid',
  '_isVue',
   '$options',
  '_renderProxy',
  '_self',
   '$parent',
   '$root',
   '$children',
   '$refs',
  '_watcher',
  '_inactive',
  '_directInactive',
  '_isMounted',
  '_isDestroyed',
  '_isBeingDestroyed',
  '_events',
  '_hasHookEvent',
  '_vnode',
  '_staticTrees',
   '$vnode',
   '$slots',
   '$scopedSlots',
  '_c',
   '$createElement',
   '$attrs',
   '$listeners',
  '_routerRoot',
  '_router',
  '_route',
  '_bv__modal',
  '_bv__toast',
  '_vueMeta',
  'nuxt',
  '_watchers',
  'refreshOnlineStatus',
  'refresh',
  'errorChanged',
  'setLayout',
  'loadLayout',
  '_data',
  'layoutName',
  'layout',
  'isOnline',
  '_computedWatchers',
  'isOffline',
  'error',
   'context'
]

ویژگی‌های زمینهٔ سرور در صفحه [index] به شرح زیر است:

Liste des clés [[home server created], this.$nuxt.context]
[
  'isStatic',
  'isDev',
  'isHMR',
  'app',
  'payload',
  'error',
  'base',
  'env',
  'req',
  'res',
  'ssrContext',
  'redirect',
  'beforeNuxtRender',
  'route',
  'next',
  '_redirected',
  '_errored',
  'params',
  'query',
   '$axios'
]

این‌ها همان ویژگی‌هایی هستند که در شی [context] افزونه وجود دارند.

10.5. پلاگینی که توسط کلاینت اجرا می‌شود

پس از اینکه سرور صفحه [index] را به مرورگر کلاینت ارسال کرد، اسکریپت‌های سمت کلاینت کنترل را در دست می‌گیرند. سپس پلاگین [main.js] اجرا خواهد شد. این لاگ‌ها به شرح زیر هستند:

[main server], process.server= false process.client= true
[main client], il y a 2 arguments
Liste des clés [[main client], context]
Array(17)0: "isStatic"1: "isDev"2: "isHMR"3: "app"4: "payload"5: "error"6: "base"7: "env"8: "redirect"9: "nuxtState"10: "route"11: "next"12: "_redirected"13: "_errored"14: "params"15: "query"16: "$axios"length: 17__proto__: Array(0)
Liste des clés [[main client], context.app]
Array(14)0: "router"1: "nuxt"2: "head"3: "render"4: "data"5: "beforeCreate"6: "created"7: "mounted"8: "watch"9: "computed"10: "methods"11: "components"12: "context"13: "$axios"length: 14__proto__: Array(0)
Liste des clés [[main client], context.route]
Array(8)0: "name"1: "meta"2: "path"3: "hash"4: "query"5: "params"6: "fullPath"7: "matched"length: 8__proto__: Array(0)
[main client], context.route= ObjectfullPath: "/"hash: ""matched: [{…}]meta: [{…}]name: "index"params: {}path: "/"query: {}__proto__: Object
Liste des clés [[main client], context.app.router]
Array(10)0: "app"1: "apps"2: "options"3: "beforeHooks"4: "resolveHooks"5: "afterHooks"6: "matcher"7: "fallback"8: "mode"9: "history"length: 10__proto__: Array(0)
Liste des clés [[main client], context.app.router.options.routes]
Array(3)0: "0"1: "1"2: "2"length: 3__proto__: Array(0)
[main client], context.app.router.options.routes= Array(3)0: {path: "/page1", name: "page1", component: ƒ}1: {path: "/page2", name: "page2", component: ƒ}2: {path: "/", name: "index", component: ƒ}length: 3__proto__: Array(0)
inject= function

ما ویژگی‌هایی مشابه با آنچه در سمت سرور یافت می‌شود را می‌بینیم، با این تفاوت که برخی ویژگی‌ها ناپدید شده و برخی دیگر ظاهر شده‌اند. برای مثال، در خط ۴، ویژگی‌های [req, res] — که شامل درخواست‌های HTTP از مرورگر مشتری و پاسخ HTTP از سرور بودند — وجود ندارند.

10.6. صفحهٔ کلاینت [index]

صفحهٔ مشتری [index] گزارش‌های زیر را تولید می‌کند:

1
2
3
4
5
6
7
8
[home beforeCreate]
[home client created]
Liste des clés [[home client created], this.$nuxt]
(51) ["_uid", "_isVue", "$options", "_renderProxy", "_self", "$parent", "$root", "$children", "$refs", "_watcher", "_inactive", "_directInactive", "_isMounted", "_isDestroyed", "_isBeingDestroyed", "_events", "_hasHookEvent", "_vnode", "_staticTrees", "$vnode", "$slots", "$scopedSlots", "_c", "$createElement", "$attrs", "$listeners", "_routerRoot", "_router", "_route", "_bv__modal", "_bv__toast", "_vueMeta", "nuxt", "_watchers", "refreshOnlineStatus", "refresh", "errorChanged", "setLayout", "loadLayout", "_data", "layoutName", "layout", "isOnline", "_computedWatchers", "isOffline", "error", "context", "_name", "setTransitions", "$loading", "$el"]
Liste des clés [[home client created], this.$nuxt.context]
(17) ["isStatic", "isDev", "isHMR", "app", "payload", "error", "base", "env", "redirect", "nuxtState", "route", "next", "_redirected", "_errored", "params", "query", "$axios"]
[home client beforeMount]
[home client mounted]
  • خط ۴: ویژگی‌های شیء [this.$nuxt]. این یک شیء غنی با ۵۱ ویژگی است؛
  • خط ۶: ویژگی‌های شیء [this.$nuxt.context]. این‌ها همان ویژگی‌های موجود در شیء [context] از افزونهٔ کلاینت هستند؛