Skip to content

13. مثال [nuxt-10]: asyncData و بارگذاری

تابع [asyncData] درون یک صفحه امکان بارگذاری ناهمزمان داده‌ها – اغلب از منابع خارجی – را فراهم می‌کند. [nuxt] منتظر تکمیل تابع [asyncData] می‌ماند قبل از آغاز چرخهٔ عمر صفحه. بنابراین صفحه تنها پس از دریافت داده‌های خارجی رندر می‌شود. این تابع هم توسط سرور و هم توسط کلاینت طبق قوانین زیر اجرا می‌شود:

  • وقتی صفحه مستقیماً از سرور درخواست می‌شود، تنها سرور تابع [asyncData] را اجرا می‌کند؛
  • در ادامه، در طول ناوبری سمت کلاینت، تنها کلاینت تابع [asyncData] را اجرا می‌کند؛

در نهایت، تنها یکی از این دو – کلاینت یا سرور – این تابع را اجرا می‌کند. علاوه بر این، هنگامی که کلاینت تابع [asyncData] را اجرا می‌کند، [nuxt] یک نوار پیشرفت را نمایش می‌دهد که قابل پیکربندی است.

تابع [asyncData] این امکان را فراهم می‌کند که صفحات به همراه داده‌هایشان به موتورهای جستجو ارائه شوند و آن‌ها را مرتبط‌تر سازد.

مثال [nuxt-10] در ابتدا با کپی کردن پروژه [nuxt-01] ایجاد می‌شود:

Image

فقط صفحه [page1] تغییر می‌کند.

13.1. صفحه [page1]

کد صفحه [page1] به شرح زیر است:


<!-- نما شمارهٔ ۱ -->
<template>
  <Layout :left="true" :right="true">
    <!-- ناوبری -->
    <Navigation slot="left" />
    <!-- پیام-->
    <b-alert slot="right" show variant="primary"> Page 1 -- result={{ result }} </b-alert>
  </Layout>
</template>

<script>
/*eslint-disable no-console */
/* eslint-disable nuxt/no-timing-in-fetch-data */

import Navigation from '@/components/navigation'
import Layout from '@/components/layout'

export default {
  name: 'Page1',
  // کامپوننت‌های استفاده شده
  components: {
    Layout,
    Navigation
  },
  // داده‌های ناهمزمان
  asyncData(context) {
    // لاگ
    console.log('[page1 asyncData started]')
    // بازگرداندن یک پرامیس
    return new Promise(function(resolve, reject) {
      // شبیه‌سازی یک تابع ناهمزمان
      setTimeout(function () {
        // بازگرداندن نتیجهٔ ناهمزمان – یک عدد تصادفی در اینجا
        resolve({ result: Math.floor(Math.random() * Math.floor(100)) })
        // لاگ
        console.log('[page1 asyncData finished]')
      }, 5000)
    })
  },

  //چرخهٔ زندگی
  beforeCreate() {
    console.log('[page1 beforeCreate]')
  },
  created() {
    console.log('[page1 created]')
  },
  beforeMount() {
    console.log('[page1 beforeMount]')
  },
  mounted() {
    console.log('[page1 mounted]')
  }
}
</script>
  • خطوط ۲۶–۳۹: تابع [asyncData]. ما قبلاً این تابع را بررسی کرده‌ایم (به بخش مرتبط مراجعه کنید). این تابع قبل از چرخه عمر صفحه اجرا می‌شود. به همین دلیل، کلمه کلیدی [this] نمی‌تواند در داخل تابع استفاده شود؛
  • خط ۳۰: باید یک promise از نوع [Promise] بازگرداند یا از سینتکس async/await استفاده کند؛
  • خطوط ۳۲–۳۷: رفتار غیرهم‌زمان (asynchronous) promise با یک وقفه ۵ ثانیه‌ای شبیه‌سازی می‌شود (خط ۳۷);
  • خط ۳۴: نتیجه تابع غیرهمزمان به صورت یک شی {result:...} بازگردانده می‌شود. شی غیرهمزمانی که توسط تابع [asyncData] بازگردانده می‌شود، در شی [data] صفحه گنجانده می‌شود. به همین دلیل است که شیء [result] در خط ۷ قالب در دسترس است، هرچند که صفحه شیء [data] را تعریف نکرده بود؛

13.2. پیکربندی نوار پیشرفت [asyncData]

زمانی که صفحه [page1] هدف یک ناوبری در کلاینت (حالت SPA) باشد، کلاینت تابع [asyncData] را اجرا می‌کند، و سپس [nuxt] یک نوار پیشرفت را نمایش می‌دهد، که پس از بازگشت نتیجه تابع [asyncData] آن را مخفی می‌کند. ویژگی [loading] از فایل [nuxt.config.js] به شما امکان می‌دهد این نوار را پیکربندی کنید:


loading: {
    color: 'blue',
    height: '5px',
    throttle: 200,
    continuous: true
},

به طور پیش‌فرض، تصویر بارگذاری برای [nuxt] یک نوار پیشرفت است که تمام عرض صفحه را در بر می‌گیرد. این نوار دارای رنگ و ضخامت است. نوار رنگی به تدریج از 0% تا 100% بزرگ‌تر می‌شود، با سرعتی که بسته به مدت زمان انتظار متغیر است.

  • خط ۲: رنگ نوار پیشرفت را تعیین می‌کند؛
  • خط ۳: ضخامت نوار را به پیکسل تنظیم می‌کند؛
  • خط ۴: [throttle] تأخیر به میلی‌ثانیه قبل از شروع انیمیشن است. این امر تضمین می‌کند که وقتی تابع [asyncData] سریعاً نتیجه خود را بازمی‌گرداند، هیچ انیمیشنی نمایش داده نشود؛
  • خط ۵: [continuous] رفتار انیمیشن نوار پیشرفت را تعیین می‌کند. به‌طور پیش‌فرض، نوار به‌تدریج از ۰٪ تا ۱۰۰٪ اندازه خود رشد می‌کند، با سرعتی که بسته به زمان انتظار متغیر است. با [continuous:true]، نوار رنگی با سرعت ثابت از ۰ تا ۱۰۰ درصد اندازه خود گسترش می‌یابد، سپس این فرآیند را تا زمانی که تابع [asyncData] نتیجه خود را بازگردانده است، تکرار می‌کند؛

13.3. Exécution

بیایید برنامه را راه‌اندازی کنیم، سپس به‌صورت دستی صفحه [page1] را از سرور درخواست کنیم:

Image

لاگ‌ها به شرح زیر است:

Image

  • می‌توانیم ببینیم که تنها سرور [1] تابع [asyncData] را اجرا کرده است، و این کار را قبل از چرخه صفحه انجام داده است؛

اکنون بیایید صفحه ارسال‌شده توسط سرور (کد منبع) را بررسی کنیم:


<!doctype html>
<html data-n-head-ssr>
<head>
  <title>Introduction à [nuxt.js]</title>
  <meta data-n-head="ssr" charset="utf-8">
  <meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
  <meta data-n-head="ssr" data-hid="description" name="description" content="ssr routing loading asyncdata middleware plugins store">
  <link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
  <base href="/nuxt-10/">
  <link rel="preload" href="/nuxt-10/_nuxt/runtime.js" as="script">
  <link rel="preload" href="/nuxt-10/_nuxt/commons.app.js" as="script">
  <link rel="preload" href="/nuxt-10/_nuxt/vendors.app.js" as="script">
  <link rel="preload" href="/nuxt-10/_nuxt/app.js" as="script">
...
</head>
<body>
  <div data-server-rendered="true" id="__nuxt">
    <div id="__layout">
      <div class="container">
        <div class="card">
          <div class="card-body">
            <div role="alert" aria-live="polite" aria-atomic="true" align="center" class="alert alert-success">
            <h4>[nuxt-10] : asyncData et loading</h4>
              </div>
            <div>
              <div class="row">
                <div class="col-2">
                  <ul class="nav flex-column">
                    <li class="nav-item">
                      <a href="/nuxt-10/" target="_self" class="nav-link">
                        Home
                      </a>
                    </li>
                    <li class="nav-item">
                      <a href="/nuxt-10/page1" target="_self" class="nav-link active nuxt-link-active">
                        Page 1
                      </a>
                    </li>
                    <li class="nav-item">
                      <a href="/nuxt-10/page2" target="_self" class="nav-link">
                        Page 2
                      </a>
                    </li>
                  </ul>
                </div> <div class="col-10"><div role="alert" aria-live="polite" aria-atomic="true" class="alert alert-primary"> Page 1 -- result=3 </div></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <script>window.__NUXT__ = (function (a, b, c) {
  return {
    layout: "default", data: [{ result: 3 }], error: null, serverRendered: true,
    logs: [
      { date: new Date(1574939615256), args: ["[page1 asyncData started]"], type: a, level: b, tag: c },
      { date: new Date(1574939620263), args: ["[page1 asyncData finished]"], type: a, level: b, tag: c },
      { date: new Date(1574939620285), args: ["[page1 beforeCreate]"], type: a, level: b, tag: c },
      { date: new Date(1574939620287), args: ["[page1 created]"], type: a, level: b, tag: c }
    ]
  }
    }("log", 2, ""));</script>
  <script src="/nuxt-10/_nuxt/runtime.js" defer></script>
  <script src="/nuxt-10/_nuxt/commons.app.js" defer></script>
  <script src="/nuxt-10/_nuxt/vendors.app.js" defer></script>
  <script src="/nuxt-10/_nuxt/app.js" defer></script>
</body>
</html>
  • خط ۵۵: می‌بینیم که سرور یک آرایه به نام [data] را برای کلاینت ارسال کرده است که شامل شی [result:3] است، و این شی در شی [data] از صفحه سرور به نام [page1] جاسازی شده بود. برای اینکه کلاینت نیز بتواند همین کار را انجام دهد و در نتیجه همان صفحه را مانند سرور نمایش دهد، سرور شیء [result] را برای کلاینت ارسال می‌کند. توجه باید داشت که کلاینت تابع [asyncData] را اجرا نخواهد کرد. این شیء صرفاً از داده‌های محاسبه شده توسط سرور استفاده خواهد کرد؛

اکنون با استفاده از منوی ناوبری از صفحه [Home] به صفحه [Page 1] برویم:

Image

  • در صفحه [1]، نوار پیشرفت ظاهر می‌شود؛

پس از ۵ ثانیه، به صفحه [Page 1] می‌رسیم:

Image

لاگ‌ها به شرح زیر است:

Image

می‌توانیم ببینیم که کلاینت تابع [asyncData] را قبل از چرخهٔ عمر صفحه اجرا کرده است.