13. مثال [nuxt-10]: asyncData و بارگذاری
تابع [asyncData] درون یک صفحه امکان بارگذاری ناهمزمان دادهها – اغلب از منابع خارجی – را فراهم میکند. [nuxt] منتظر تکمیل تابع [asyncData] میماند قبل از آغاز چرخهٔ عمر صفحه. بنابراین صفحه تنها پس از دریافت دادههای خارجی رندر میشود. این تابع هم توسط سرور و هم توسط کلاینت طبق قوانین زیر اجرا میشود:
- وقتی صفحه مستقیماً از سرور درخواست میشود، تنها سرور تابع [asyncData] را اجرا میکند؛
- در ادامه، در طول ناوبری سمت کلاینت، تنها کلاینت تابع [asyncData] را اجرا میکند؛
در نهایت، تنها یکی از این دو – کلاینت یا سرور – این تابع را اجرا میکند. علاوه بر این، هنگامی که کلاینت تابع [asyncData] را اجرا میکند، [nuxt] یک نوار پیشرفت را نمایش میدهد که قابل پیکربندی است.
تابع [asyncData] این امکان را فراهم میکند که صفحات به همراه دادههایشان به موتورهای جستجو ارائه شوند و آنها را مرتبطتر سازد.
مثال [nuxt-10] در ابتدا با کپی کردن پروژه [nuxt-01] ایجاد میشود:

فقط صفحه [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] را از سرور درخواست کنیم:

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

- میتوانیم ببینیم که تنها سرور [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] برویم:

- در صفحه [1]، نوار پیشرفت ظاهر میشود؛
پس از ۵ ثانیه، به صفحه [Page 1] میرسیم:

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

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