مكوّن Vue Suspense
مع Slots default و#fallback، وتحميل المكوّنات غير المتزامنة، وSuspense المتداخل
مكوّن Vue Suspense درس مجاني في Vue Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Vue Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Vue Academy 4 دروس في المجموع.
ما الذي تحلّه Suspense
Suspense مكوّن مضمّن في Vue ينسّق حالات التحميل للمكوّنات التي تتضمن تبعيات غير متزامنة.
من دونه، يدير كل مكوّن غير متزامن مؤشر التحميل الخاص به. أما باستخدام Suspense، فتصرّح بحدّ واحد ينتظر كل العمليات غير المتزامنة المتداخلة ويعرض محتوى بديلًا واحدًا إلى أن يصبح كل شيء جاهزًا.
فتحتان: default وfallback
يوفّر Suspense فتحتين مسمّاتين:
- default — المحتوى الفعلي، وقد يتضمن مكوّنات غير متزامنة أو
setup()غير متزامنة - fallback — ما ينبغي عرضه أثناء حل الفتحة الافتراضية
عند استقرار جميع التبعيات غير المتزامنة، يستبدل Vue المحتوى البديل بالمحتوى الافتراضي.
<template>
<Suspense>
<template #default>
<UserDashboard />
</template>
<template #fallback>
<div class="spinner">Loading dashboard...</div>
</template>
</Suspense>
</template>Async setup() كتبعية
يصبح المكوّن تبعيةً غير متزامنة عندما تُعرَّف دالة setup() الخاصة به باستخدام async وتنتظر شيئًا ما. ويتتبّع Vue الوعد المُعاد.
أما المكافئ باستخدام <script setup> فهو استخدام await على المستوى الأعلى مباشرةً داخل الكتلة.
<script setup>
import { ref } from 'vue'
// Top-level await makes this an async dependency of Suspense
const res = await fetch('/api/profile')
const profile = ref(await res.json())
</script>
<template>
<h1>Welcome, {{ profile.name }}</h1>
</template>المكوّنات غير المتزامنة مشمولة أيضًا
تتتبّع Suspense أيضًا المكوّنات المُنشأة باستخدام defineAsyncComponent. ويظل المحتوى البديل ظاهرًا إلى أن تُحلّ عملية import() الديناميكية.
يتيح لك ذلك تقسيم المكوّنات الثقيلة إلى أجزاء دون كتابة واجهة تحميل لكل مكوّن.
<script setup>
import { defineAsyncComponent } from 'vue'
const Chart = defineAsyncComponent(() =>
import('./HeavyChart.vue')
)
</script>
<template>
<Suspense>
<Chart />
<template #fallback>Preparing chart...</template>
</Suspense>
</template>انتظار عدة أبناء غير متزامنين معًا
إذا احتوت الفتحة الافتراضية على عدة تبعيات غير متزامنة، فإن Suspense ينتظر اكتمال جميعها قبل إظهار المحتوى.
يمنع ذلك تغيّر تخطيط الصفحة نتيجة ظهور المكونات واحدًا تلو الآخر.
<template>
<Suspense>
<div>
<UserStats /> <!-- async setup -->
<RecentOrders /> <!-- async setup -->
<Recommendations /> <!-- async component -->
</div>
<template #fallback>
<PageSkeleton />
</template>
</Suspense>
</template>التقاط حالات الرفض باستخدام onErrorCaptured
إذا فشل setup() غير المتزامن (على سبيل المثال، بسبب فشل طلب الجلب)، ينتقل الخطأ إلى أقرب hook باسم onErrorCaptured في مكوّن أب.
لا يعرض Suspense الأخطاء بنفسه، لذلك يُقرن مع حدّ للأخطاء.
<script setup>
import { ref, onErrorCaptured } from 'vue'
const error = ref(null)
onErrorCaptured((err) => {
error.value = err
return false // stop the error from propagating further
})
</script>نمط حدّ الأخطاء + Suspense
يضع النمط الشائع في بيئة الإنتاج Suspense داخل مكوّن يعمل كحدّ للأخطاء. يعيد onErrorCaptured القيمة false لإيقاف انتشار الخطأ وعرض واجهة خطأ بدلًا من ذلك.
<script setup>
import { ref, onErrorCaptured } from 'vue'
const err = ref(null)
onErrorCaptured((e) => { err.value = e; return false })
</script>
<template>
<p v-if="err">Failed to load: {{ err.message }}</p>
<Suspense v-else>
<ProfilePanel />
<template #fallback>Loading...</template>
</Suspense>
</template>حدثا pending وresolve
يصدر Suspense أحداث دورة حياة يمكنكم الاستماع إليها:
- @pending — يُطلَق عند الدخول في حالة الانتظار (التحميل)
- @resolve — يُطلَق عند اكتمال حل الفتحة الافتراضية
- @fallback — يُطلَق عند عرض محتوى البديل
يفيد ذلك في التحليلات أو أشرطة التقدم.
<template>
<Suspense @pending="onPending" @resolve="onResolve">
<RouteView />
<template #fallback>Loading route...</template>
</Suspense>
</template>خاصية timeout للبديل المتأخر
تؤخر خاصية timeout (بالمللي ثانية) عرض البديل. إذا اكتمل العمل غير المتزامن قبل انتهاء المهلة، فلن يظهر البديل مطلقًا.
يمنع ذلك الظهور الخاطف لمؤشر التحميل عند الاستجابات السريعة.
<template>
<!-- Only show fallback if loading exceeds 200ms -->
<Suspense :timeout="200">
<FastPanel />
<template #fallback>Loading...</template>
</Suspense>
</template>استخدام Suspense مع Router والانتقالات
يتكامل Suspense مع RouterView وTransition لتحريك تغيّرات المسارات غير المتزامنة. الترتيب مهم: يغلّف Transition المكوّن Suspense، الذي يغلّف بدوره المكوّن المرتبط بالمسار.
<template>
<RouterView v-slot="{ Component }">
<Transition mode="out-in">
<Suspense>
<component :is="Component" />
<template #fallback>Loading page...</template>
</Suspense>
</Transition>
</RouterView>
</template>متى لا تستخدموا Suspense
تجنبوا استخدام Suspense للبيانات التي يُعاد جلبها كثيرًا بينما يظل المكوّن مثبتًا — فهو يدير الحل غير المتزامن الأولي فقط. أما حالات التحميل المستمرة (مثل الترقيم وإعادة الجلب)، فاستخدموا بدلًا منه مرجعًا تفاعليًا عاديًا باسم loading.
<script setup>
import { ref } from 'vue'
const loading = ref(false)
async function loadMore() {
loading.value = true
await fetchNextPage()
loading.value = false
}
</script>تحقق سريع
اختبروا مدى فهمكم لـ Suspense.
مراجعة
تعلمتم كيف ينسّق Suspense التبعيات غير المتزامنة:
- تحتوي الفتحة default على المحتوى غير المتزامن (مثل setup غير المتزامن أو المكونات غير المتزامنة)
- تعرض الفتحة fallback المحتوى أثناء التحميل
- ينتظر جميع الأبناء غير المتزامنين قبل إظهار المحتوى
- تنتقل حالات الرفض إلى
onErrorCapturedفي حدّ أخطاء لدى مكوّن أب - تمنع
timeoutالظهور الخاطف لمؤشر التحميل، وتفيد أحداث مثل@resolveفي التحليلات
الأسئلة الشائعة
هل درس «مكوّن Vue Suspense» مجاني؟
نعم — نص درس «مكوّن Vue Suspense» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Vue Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Vue Academy 4 دروس في المجموع.
ماذا ستتعلم في «مكوّن Vue Suspense»؟
مع Slots default و#fallback، وتحميل المكوّنات غير المتزامنة، وSuspense المتداخل تتمرن على Vue Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Vue Academy؟
لا تُشترط خبرة سابقة. Vue Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «مكوّن Vue Suspense»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Vue Academy هذا؟
نعم. كل درس في Vue Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مكوّن Vue Suspense
- المكوّنات غير المتزامنة باستخدام defineAsyncComponent
- SSR المتدفق باستخدام renderToWebStream
- استراتيجيات Hydration المؤجلة