Vue.js: العرض الشرطي والقوائم
آخر تحديث: 2026-10-20
يُعد العرض الشرطي (v-if / v-show) وعرض القوائم (v-for) أكثر التوجيهات استخدامًا في قوالب Vue. يتحكم الأول في ما إذا كان العنصر سيُعرض أم لا، بينما يتحكم الثاني في عدد العناصر التي يتم عرضها. ويمكن لهذين التوجيهين معًا التعامل مع 90% من سيناريوهات واجهة المستخدم.
يُعد فهم الاختلافات الخمسة الرئيسية بين v-if وv-for، بالإضافة إلى الاستخدام الصحيح لـ :key، أمرًا ضروريًا لتطوير تطبيقات Vue عالية الأداء.
1. ما ستتعلمه
العرض المشروط
- الفروق الخمسة الرئيسية بين
v-showوv-if v-forالتكرار على المصفوفات والكائنات والأرقام والسلاسل- الغرض من
:keyوأفضل الممارسات المتعلقة به templateتغليف عناصر متعددة- تصفية القوائم وفرزها وتقسيمها إلى صفحات
- تحسين التمرير الافتراضي (أكثر من 10,000 عنصر)
2. كابوس البرمجة: «عبارات if المتداخلة» في لوحة المعلومات
(1) المشكلة: 5 علامات v-if متداخلة — كابوس في عملية تصحيح الأخطاء
خرج كود لوحة التحكم الخاصة بأليس عن السيطرة:
مراجعة الكود من تشارلي:
"أليس، هذا غير قابل للقراءة. هناك 5 مستويات من التداخل في عبارات v-if. ماذا لو أضفنا شرطين آخرين؟ نحن بحاجة إلى نمط أكثر بساطة."
(2) حل Vue: التسوية باستخدام v-if + الخصائص المحسوبة
(3) الإيرادات
- سهولة القراءة: 5 مستويات من التداخل → 6 أسطر مرتبة جنبًا إلى جنب
- قابلية الصيانة: لإضافة شرط، ما عليك سوى إضافة سطر واحد من
v-else-if - تصحيح الأخطاء: لكل سطر شرطه الخاص، مما يسهل تعيين نقاط التوقف
3. العرض الشرطي باستخدام v-if / v-else-if / v-else
(1) قواعد النحو الأساسية
(2) العنصر template
(3) 5 حالات استخدام رئيسية
| السيناريو | استخدام v-if |
|---|---|
| مسجل الدخول/غير مسجل الدخول | ✅ |
| قيد التحميل.../تم التحميل | ✅ |
| لا توجد بيانات/تتوفر بيانات | ✅ |
| status الخطأ | ✅ |
| التبديل المتكرر بين إظهار/إخفاء | ❌ (استخدم v-show) |
▶ مثال: 5 طرق لاستخدام v-if/v-show
▶ جرّب الكودالإخراج:
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) توصيات الاختيار
// 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
▶ جرّب الكود
الإخراج:
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 ضروريًا؟
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:
- مقارنة استخدام
indexفي Vue - بعد إزالة A، يصبح B/C (0)/(1)، لكن Vue تعتقد أن «B/C لا يزال موجودًا»
- يؤدي إلى عدم توافق status المكونات
عندما يكون :key موجودًا:
- مقارنة المعرّفات في Vue
- تحديد العناصر التي تمت إضافتها أو حذفها أو نقلها بدقة
- الأداء الأمثل
(3) أفضل الممارسات لـ :key
<!-- ✅ 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
▶ جرّب الكودالإخراج:
user.id → الخيار الأفضل عند الفرز
user.email أو مفتاح مركّب → بديل فريد
index → يعمل لكنه يربك الصفوف عند الفرز
Math.random() → إعادة إنشاء الصفوف في كل عرض
7. تصفية القوائم / الفرز / تقسيم الصفحات
(1) التصفية + الفرز (الخصائص المحسوبة)
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) ترقيم الصفحات
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
<!-- 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>
الإخراج:
في Vue 3 أولوية v-if أعلى من v-for
جمعهما على العنصر نفسه ينتج خطأ شائعًا
الحل: computed يفلتر القائمة قبل العرض
template يفصل الشرط عن الحلقة
8. تمرين شامل: تصفية القوائم + الفرز + تقسيم الصفحات
▶ مثال: تطبيق كامل على تصفية القوائم + الفرز + تقسيم الصفحات
▶ جرّب الكودالإخراج:
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 للتمرير الافتراضي |
❓ أسئلة شائعة
:key مطلوب مع v-for؟:key لتجنب مشاكل الأداء وعدم تطابق حالات المكونات. يُفضل استخدام معرّف فريد (item.id)، يليه index؛ ولا تستخدم random() أبدًا.template أو التصفية باستخدام computed.template؟template هو عنصر غلاف منطقي في Vue لا يتم عرضه في DOM. ويُستخدم لتجنب ظهور عناصر div غير الضرورية عندما يتضمن v-if أو v-for عناصر متعددة.:key؛ (2) استخدم computed لتخزين النتائج المؤقتة في cache لتصفية/فرزها؛ (3) بالنسبة للقوائم الكبيرة (100,000+)، استخدم vue-virtual-scroller للتمرير الافتراضي لعرض المنطقة المرئية فقط.v-for؟v-for="(value, key, index) in obj"، ترتيب المعلمات: القيمة، المفتاح، الفهرس.<div v-if="item.length">Column </div><div v-else> Data</div>.activeIndex إلى كل عنصر: @click="activeIndex = item.id" :classe="{ active: activeIndex === item.id }".📖 ملخص
- العرض الشرطي باستخدام v-if (يُزيل العنصر من DOM)، بينما تعمل v-show على تبديل status الخاصية
display(تظل دائمًا موجودة في DOM) - استخدم
v-ifللتغييرات العرضية وv-showللتغييرات المتكررة - استخدم
v-forللتكرار عبر المصفوفات والكائنات والأرقام والسلاسل؛ واستخدم:keyلتحسين الأداء - :key: يُفضل استخدام معرّف فريد؛ ويُعد الفهرس الخيار الثاني الأفضل؛ ولا تستخدم الدالة random()
- العنصر
templateيضم عدة عناصر ولا يتم عرضه في DOM - تصفية قائمة cache وفرزها وتقسيمها إلى صفحات تلقائيًا باستخدام
computed - في Vue 3،
v-ifله الأسبقية علىv-for - تحسين عرض القوائم الكبيرة باستخدام التمرير الافتراضي (أكثر من 100,000 عنصر)
📝 تمارين
-
أسئلة أساسية (مستوى الصعوبة: ⭐)
استخدم v-if/v-else للتبديل بين حالتي تسجيل الدخول وتسجيل الخروج:
- تم تسجيل الدخول: يعرض اسم المستخدم وزر «تسجيل الخروج»
- لم يتم تسجيل الدخول: يعرض عبارة «يرجى تسجيل الدخول» ونموذج تسجيل الدخول
- استخدم «موديلو» لتجميع عناصر متعددة
-
مسائل متقدمة (مستوى الصعوبة: ⭐⭐)
تنفيذ قائمة المهام باستخدام
v-for:- 3 حالات: الكل / قيد التنفيذ / مكتمل (يمكنك التبديل بينها باستخدام الأزرار الثلاثة)
- تعرض القائمة المهام مع الstatus المقابلة لها
- يحتوي كل عنصر على زرين هما «إكمال» و«حذف»
- تظهر العبارة «غير مكتمل: N عنصر» في الأسفل
-
مسألة التحدي (مستوى الصعوبة: ⭐⭐⭐)
تنفيذ نظام متكامل لتصفية المنتجات وفرزها وتقسيمها إلى صفحات (5 ملفات):
- بيانات المنتج: 30 سجلًا، تشمل الاسم والسعر والفئة وتاريخ الإنشاء
- البحث: إجراء بحث تقريبي حسب الاسم
- التصفية حسب الفئة: 5 فئات (الكل/الهاتف/الكمبيوتر المحمول/الجهاز اللوحي/سماعات الرأس)
- الترتيب حسب: السعر (تصاعدي/تنازلي)، الاسم، الأحدث
- ترقيم الصفحات: 10 عناصر في كل صفحة، مع التنقل باستخدام أرقام الصفحات
- الأداء: تخزين النتائج المحسوبة والمصفاة/المرتبة في ذاكرة التخزين المؤقت
- تحسين القوائم الكبيرة: 1,000 عنصر اختبار لضمان الأداء السلس