Skip to content

13. مثال [nuxt-10]: asyncData و loading

تسمح وظيفة [asyncData] في الصفحة بتحميل البيانات، التي غالبًا ما تكون خارجية، بشكل غير متزامن. تنتظر [nuxt] انتهاء وظيفة [asyncData] قبل بدء دورة حياة الصفحة. وبالتالي، لا يتم عرض الصفحة إلا بعد الحصول على البيانات الخارجية. يتم تنفيذها من قبل كل من الخادم والعميل وفقًا للقواعد التالية:

  • عندما يتم طلب الصفحة مباشرة من الخادم، يقوم الخادم وحده بتنفيذ الوظيفة [asyncData
  • ثم أثناء تصفح العميل، يقوم العميل وحده بتنفيذ الدالة [asyncData

في النهاية، يقوم أحدهما فقط، سواء العميل أو الخادم، بتنفيذ الوظيفة. علاوة على ذلك، عندما يقوم العميل بتنفيذ الوظيفة [asyncData]، تعرض الوظيفة [nuxt] شريط تقدم يمكن ضبطه.

تسمح الوظيفة [asyncData] بتزويد محركات البحث بصفحات تحتوي على بياناتها، مما يجعلها أكثر أهمية.

يتم الحصول على المثال [nuxt-10] في البداية عن طريق نسخ المشروع [nuxt-01]:

Image

تتغير الصفحة [page1] فقط.

13.1. الصفحة [page1]

رمز الصفحة [page1] هو التالي:


<!-- الطريقة رقم 1 -->
<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>
  • الأسطر 26-39: الدالة [asyncData]. لقد درسنا هذه الدالة بالفعل (انظر الفقرة المرتبطة). يتم تنفيذها قبل دورة حياة الصفحة. ولهذا السبب، لا يمكن استخدام الكلمة الرئيسية [this] في الدالة؛
  • السطر 30: يجب أن تعيد وعدًا [Promise] أو تستخدم صيغة async / await؛
  • الأسطر 32-37: يتم محاكاة الدالة غير المتزامنة للوعد بفترة انتظار مدتها 5 ثوانٍ (السطر 37)؛
  • السطر 34: يتم عرض نتيجة الدالة غير المتزامنة في شكل كائن {result :...}. يتم دمج الكائن غير المتزامن الذي تعرضه الدالة [asyncData] في الكائن [data] للصفحة. ولهذا السبب يكون الكائن [result] متاحًا في السطر 7 من القالب حتى وإن لم تكن الصفحة قد حددت كائن [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٪ من حجمه، بسرعة أكبر أو أقل حسب مدة الانتظار.

  • السطر 2: يحدد لون شريط التقدم؛
  • السطر 3: يحدد سمك الشريط بالبكسل؛
  • السطر 4: [throttle] هو الوقت بالمللي ثانية قبل بدء الرسوم المتحركة. وهذا يمنع ظهور صورة متحركة عندما تعرض الدالة [asyncData] نتيجتها بسرعة؛
  • السطر 5: [continuous] يحدد سلوك الرسوم المتحركة لشريط التقدم. بشكل افتراضي، يتوسع الشريط تدريجيًا من 0٪ إلى 100٪ من حجمه، بسرعة أكبر أو أقل حسب مدة الانتظار. مع [continuous:true]، ينمو الشريط الملون بسرعة ثابتة من 0 إلى 100٪ من حجمه، ثم يبدأ من جديد حتى تعرض الدالة [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>
  • السطر 55: نرى أن الخادم أرسل إلى العميل مصفوفة [data] التي تحتوي على الكائن [result:3] الذي تم دمجه في الكائن [data] للصفحة [page1] الخاصة بالخادم. ولكي يتمكن العميل من فعل الشيء نفسه وبالتالي عرض نفس الصفحة التي يعرضها الخادم، يقوم الخادم بإرسال الكائن [result] إليه. نذكر أن العميل لن يقوم بتنفيذ الدالة [asyncData]. بل سيستخدم ببساطة البيانات التي قام الخادم بحسابها؛

الآن، دعونا ننتقل من الصفحة [Home] إلى الصفحة [Page 1] باستخدام قائمة التنقل:

Image

  • في [1]، نرى شريط التقدم يظهر؛

بعد 5 ثوانٍ، تظهر الصفحة [Page 1]:

Image

السجلات هي كما يلي:

Image

نلاحظ أن العميل قد نفذ الوظيفة [asyncData] قبل دورة حياة الصفحة.