Vue.js: العرض الشرطي والقوائم

آخر تحديث: 2026-10-20

يُعد العرض الشرطي (v-if / v-show) وعرض القوائم (v-for) أكثر التوجيهات استخدامًا في قوالب Vue. يتحكم الأول في ما إذا كان العنصر سيُعرض أم لا، بينما يتحكم الثاني في عدد العناصر التي يتم عرضها. ويمكن لهذين التوجيهين معًا التعامل مع 90% من سيناريوهات واجهة المستخدم.

يُعد فهم الاختلافات الخمسة الرئيسية بين v-if وv-for، بالإضافة إلى الاستخدام الصحيح لـ :key، أمرًا ضروريًا لتطوير تطبيقات Vue عالية الأداء.

التوجيهات ذات صلة:v-else-if v-show v-for v-if

1. ما ستتعلمه

العرض المشروط


2. كابوس البرمجة: «عبارات if المتداخلة» في لوحة المعلومات

(1) المشكلة: 5 علامات v-if متداخلة — كابوس في عملية تصحيح الأخطاء

خرج كود لوحة التحكم الخاصة بأليس عن السيطرة:

مراجعة الكود من تشارلي:

"أليس، هذا غير قابل للقراءة. هناك 5 مستويات من التداخل في عبارات v-if. ماذا لو أضفنا شرطين آخرين؟ نحن بحاجة إلى نمط أكثر بساطة."

(2) حل Vue: التسوية باستخدام v-if + الخصائص المحسوبة

(3) الإيرادات


3. العرض الشرطي باستخدام v-if / v-else-if / v-else

(1) قواعد النحو الأساسية

(2) العنصر template

(3) 5 حالات استخدام رئيسية

السيناريو استخدام v-if
مسجل الدخول/غير مسجل الدخول ✅
قيد التحميل.../تم التحميل ✅
لا توجد بيانات/تتوفر بيانات ✅
status الخطأ ✅
التبديل المتكرر بين إظهار/إخفاء ❌ (استخدم v-show)

▶ مثال: 5 طرق لاستخدام v-if/v-show

▶ جرّب الكود

الإخراج:

TEXT
show = true → العنصران يظهران
show = false → v-if يحذف العنصر من DOM، v-show يضيف display: none
type = 'B' → يظهر B فقط
isAdmin = true → يظهر العنوان Admin والزر

4. 5 اختلافات رئيسية بين v-show و v-if

(1) الاختلافات الرئيسية

(2) 5 مقارنات رئيسية

الجانب v-if v-show
التعامل مع DOM إزالة العنصر عندما تكون الstatus غير صحيحة يبقى دائمًا في DOM؛ ويتم فقط تبديل status الخاصية display
أداء التبديل ضعيف (إزالة وإعادة إنشاء في كل مرة) جيد (CSS فقط)
العرض الأولي لا يتم العرض إذا كان الشرط غير صحيح يتم العرض دائمًا (حتى لو كان غير مرئي)
التوافق مع الانتقالات ✅ مثالي (حركات الدخول/الخروج) ❌ غير مدعوم
حالات الاستخدام التبديل من حين لآخر التبديل المتكرر

(3) توصيات الاختيار

JS
// Switch Occasionally(If you are logged in/Not logged in)→ v-if
<div v-if="isLoggedIn">Welcome, {{ user.name }}</div>
<div v-else>Please login</div>

// Frequent switching (e.g. tab switch) → v-show
<button v-show="isActive">Active</button>
<button v-show="!isActive">Inactive</button>

5. عرض القوائم باستخدام v-for

(1) التكرار عبر array

(2) التكرار على الكائنات

(3) التكرار عبر الأرقام

(4) التكرار عبر سلسلة أحرف

▶ مثال: 5 طرق لاستخدام v-for

▶ جرّب الكود

الإخراج:

TEXT
items من 3 عناصر → 3 أسطر مرقّمة 1. 2. 3.
كائن user → سطر لكل مفتاح وقيمته
الأرقام → 1 2 3 4 5
النص Hello → H e l l o

6. الغرض من :key وأفضل الممارسات

(1) ما هو :key؟

:key قم بتعيين معرّف فريد لكل عنصر من عناصر v-for لمساعدة Vue على تحديث DOM بكفاءة.

(2) لماذا يُعد :key ضروريًا؟

100%
graph LR
 A[Original List A B C] --> B[New List B C D]
 B --> C[None key:Possible misalignment]
 B --> D[Has key: Update Correctly]
 
 style C fill:#ff6b6b
 style D fill:#42b883

عندما لا يكون هناك :key:

عندما يكون :key موجودًا:

(3) أفضل الممارسات لـ :key

VUE
<!-- ✅ Recommendations:The Only One ID -->
<li v-for="user in users" :key="user.id">

<!-- ✅ Second choice:Unique Field(Email,Mobile phone number, etc.)-->
<li v-for="user in users" :key="user.email">

<!-- ❌ Avoid:index(When the data changes, the alignment is off.)-->
<li v-for="(user, index) in users" :key="index">

<!-- ❌ Never, under any circumstances:random()(Every render is different,Forced Rebuild)-->
<li v-for="user in users" :key="Math.random()">

▶ مثال: مقارنة بين 5 طرق لاستخدام :key

▶ جرّب الكود

الإخراج:

TEXT
user.id → الخيار الأفضل عند الفرز
user.email أو مفتاح مركّب → بديل فريد
index → يعمل لكنه يربك الصفوف عند الفرز
Math.random() → إعادة إنشاء الصفوف في كل عرض

7. تصفية القوائم / الفرز / تقسيم الصفحات

(1) التصفية + الفرز (الخصائص المحسوبة)

JS
import { ref, computed } from 'vue'

const items = ref([
 { id: 1, name: 'iPhone', price: 999, category: 'phone' },
 { id: 2, name: 'MacBook', price: 2499, category: 'laptop' },
 { id: 3, name: 'iPad', price: 599, category: 'tablet' }
])

const searchQuery = ref('')
const selectedCategory = ref('all')
const sortBy = ref('price') // 'price' / 'name'

// Filter + Sort(computed Automatic Caching)
const filteredItems = computed(() => {
 let result = items.value
 
 // 1. Filter by search term
 if (searchQuery.value) {
 result = result.filter(item =>
 item.name.toLowerCase().includes(searchQuery.value.toLowerCase())
 )
 }
 
 // 2. Filter by Category
 if (selectedCategory.value !== 'all') {
 result = result.filter(item => item.category === selectedCategory.value)
 }
 
 // 3. Sort
 result = [...result].sort((a, b) => {
 if (sortBy.value === 'price') return a.price - b.price
 if (sortBy.value === 'name') return a.name.localeCompare(b.name)
 return 0
 })
 
 return result
})

(2) ترقيم الصفحات

JS
const currentPage = ref(1)
const pageSize = ref(10)

// Data after pagination
const paginatedItems = computed(() => {
 const start = (currentPage.value - 1) * pageSize.value
 return filteredItems.value.slice(start, start + pageSize.value)
})

// Total Number of Pages
const totalPages = computed(() =>
 Math.ceil(filteredItems.value.length / pageSize.value)
)

▶ مثال: أولوية v-if و v-for

VUE
<!-- In Vue 3, v-if has higher priority than v-for (Vue 2 is the opposite) -->
<ul>
 <!-- Vue 3: First determine v-if, then v-for -->
 <li v-for="user in users" v-if="user.isActive" :key="user.id">
 {{ user.name }}
 </li>
 <!-- ✅ But Vue officially recommends using template to separate -->
 
 <!-- ❌ Incorrect wording(Not recommended) -->
 <li v-for="user in users" v-if="shouldShowUsers(user)" :key="user.id">
 {{ user.name }}
 </li>
 
 <!-- ✅ Recommendations:computed Filter -->
 <li v-for="user in activeUsers" :key="user.id">
 {{ user.name }}
 </li>
</template>
▶ جرّب الكود

الإخراج:

TEXT
في Vue 3 أولوية v-if أعلى من v-for
جمعهما على العنصر نفسه ينتج خطأ شائعًا
الحل: computed يفلتر القائمة قبل العرض
template يفصل الشرط عن الحلقة


8. تمرين شامل: تصفية القوائم + الفرز + تقسيم الصفحات

▶ مثال: تطبيق كامل على تصفية القوائم + الفرز + تقسيم الصفحات

▶ جرّب الكود

الإخراج:

TEXT
3 منتجات معروضة ابتداءً: iPhone و MacBook و iPad
كتابة Mac → يبقى MacBook فقط
اختيار phone → يبقى iPhone فقط
الصفحة 1 / 1 وزرّا التنقل معطّلان عند الحدين

(1) 📊 5. 5 أخطاء شائعة

الخطأ الأعراض الحل
لا شيء :key عدم توافق القائمة، ضعف الأداء إضافة :key="item.id"
استخدام v-for و v-if معًا الالتباس بشأن أولوية v-if التغليف باستخدام template أو استخدام computed
استخدام «index» كمفتاح عدم التوافق أثناء الفرز استخدام معرّف فريد
لا يدعم v-show <transition> لا يمكن تحريكه استخدم v-if بدلاً من ذلك + <transition>
القائمة كبيرة جدًا (أكثر من 100,000) تتجمد الصفحة استخدم vue-virtual-scroller للتمرير الافتراضي


التوجيهات ذات صلة:v-else-if v-show v-for v-if

❓ أسئلة شائعة

س كيف أختار بين v-if و v-show؟
ج استخدم v-if للتبديل بين الحين والآخر (لتوفير الموارد في مرحلة العرض الأولي)، واستخدم v-show للتبديل المتكرر (لتجنب إزالة بنية DOM وإعادة بنائها بشكل متكرر). استخدم v-if لحالات تسجيل الدخول/تسجيل الخروج، واستخدم v-show للتبديل بين علامات التبويب.
س هل :key مطلوب مع v-for؟
ج نوصي بشدة باستخدام :key لتجنب مشاكل الأداء وعدم تطابق حالات المكونات. يُفضل استخدام معرّف فريد (item.id)، يليه index؛ ولا تستخدم random() أبدًا.
س ما هي الأولوية عند استخدام v-if و v-for معًا؟
ج في Vue 3، يكون لـ v-if الأسبقية على v-for (على عكس Vue 2). ومع ذلك، فإن التوصية الرسمية هي تجنب استخدامهما معًا؛ وبدلاً من ذلك، يجب فصلهما باستخدام template أو التصفية باستخدام computed.
س ما الغرض من عنصر template؟
ج عنصر template هو عنصر غلاف منطقي في Vue لا يتم عرضه في DOM. ويُستخدم لتجنب ظهور عناصر div غير الضرورية عندما يتضمن v-if أو v-for عناصر متعددة.
س ماذا يمكنني أن أفعل إذا كان أداء القائمة ضعيفًا؟
ج 3 تحسينات: (1) أضف :key؛ (2) استخدم computed لتخزين النتائج المؤقتة في cache لتصفية/فرزها؛ (3) بالنسبة للقوائم الكبيرة (100,000+)، استخدم vue-virtual-scroller للتمرير الافتراضي لعرض المنطقة المرئية فقط.
س هل يمكن الوصول إلى المفاتيح والقيم عند تكرار كائن باستخدام v-for؟
ج نعم. v-for="(value, key, index) in obj"، ترتيب المعلمات: القيمة، المفتاح، الفهرس.
س كيف يمكنني عرض رسالة تنبيه في status عدم وجود بيانات؟
ج استخدم مزيجًا من v-if و v-else: <div v-if="item.length">Column </div><div v-else> Data</div>.
س كيف يمكنني تمييز عنصر محدد في قائمة؟
ج أضف activeIndex إلى كل عنصر: @click="activeIndex = item.id" :classe="{ active: activeIndex === item.id }".

📖 ملخص


📝 تمارين

  1. أسئلة أساسية (مستوى الصعوبة: ⭐)

    استخدم v-if/v-else للتبديل بين حالتي تسجيل الدخول وتسجيل الخروج:

    • تم تسجيل الدخول: يعرض اسم المستخدم وزر «تسجيل الخروج»
    • لم يتم تسجيل الدخول: يعرض عبارة «يرجى تسجيل الدخول» ونموذج تسجيل الدخول
    • استخدم «موديلو» لتجميع عناصر متعددة
  2. مسائل متقدمة (مستوى الصعوبة: ⭐⭐)

    تنفيذ قائمة المهام باستخدام v-for:

    • 3 حالات: الكل / قيد التنفيذ / مكتمل (يمكنك التبديل بينها باستخدام الأزرار الثلاثة)
    • تعرض القائمة المهام مع الstatus المقابلة لها
    • يحتوي كل عنصر على زرين هما «إكمال» و«حذف»
    • تظهر العبارة «غير مكتمل: N عنصر» في الأسفل
  3. مسألة التحدي (مستوى الصعوبة: ⭐⭐⭐)

    تنفيذ نظام متكامل لتصفية المنتجات وفرزها وتقسيمها إلى صفحات (5 ملفات):

    1. بيانات المنتج: 30 سجلًا، تشمل الاسم والسعر والفئة وتاريخ الإنشاء
    2. البحث: إجراء بحث تقريبي حسب الاسم
    3. التصفية حسب الفئة: 5 فئات (الكل/الهاتف/الكمبيوتر المحمول/الجهاز اللوحي/سماعات الرأس)
    4. الترتيب حسب: السعر (تصاعدي/تنازلي)، الاسم، الأحدث
    5. ترقيم الصفحات: 10 عناصر في كل صفحة، مع التنقل باستخدام أرقام الصفحات
    6. الأداء: تخزين النتائج المحسوبة والمصفاة/المرتبة في ذاكرة التخزين المؤقت
    7. تحسين القوائم الكبيرة: 1,000 عنصر اختبار لضمان الأداء السلس
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%