Vue.js: أساسيات المكونات
آخر تحديث: 2026-10-20
مكونات Vue هي مثيلات Vue قابلة لإعادة الاستخدام — حيث يحتوي كل مكون على نموذجه الخاص ومنطقه وأنماطه. وتتمثل البنية الأساسية لـ Vue 3 في «شجرة المكونات»: المكون الجذري (App.vue) → مكونات الصفحات → مكونات الأعمال → المكونات الأساسية (Button/Input).
يُعد إتقان أساسيات المكونات خطوة حاسمة في بناء تطبيقات Vue واسعة النطاق. سيساعدك هذا الدرس على فهم طبيعة المكونات، وكيفية تسجيلها، وقواعد تسميتها، ولماذا تُعد مكونات الملف الواحد (SFCs) هي النهج الموصى به في Vue.
1. ما ستتعلمه
- ما المقصود بالمكون؟ العلاقة بين المكونات ومثيلات Vue
- الأجزاء الثلاثة لمكون «الملف الفردي» (SFC): «template» و«script» و«style»
- الفرق بين التسجيل العالمي والتسجيل المحلي وكيفية الاختيار بينهما
- قواعد تسمية المكونات (PascalCase / kebab-case)
- إعادة استخدام المكونات (تجنب تكرار الكود)
- المفاهيم الأساسية لـ
propsوemit(سيتم تناولها بالتفصيل في الدرسين التاليين) - 5 مبادئ لتصميم المكونات
2. نظام خلفي للتجارة الإلكترونية من 30 صفحة يعاني من تكرار الأكواد
(1) المشكلة: 30 بطاقة منتج، و30 عملية نسخ ولصق
كانت مسؤولة التجارة الإلكترونية لدى أليس بحاجة إلى عرض 30 بطاقة منتج على عدة صفحات. وكانت طريقتها الأولية هي:
<!-- ❌ The "Broken" Version: Copy Product Card 30 times -->
<!-- In HomeView.vue -->
<div class="product-card">
<img src="iphone.jpg">
<h3>iPhone 15 Pro</h3>
<p>$999</p>
<button>Add to Cart</button>
</div>
<div class="product-card">
<img src="macbook.jpg">
<h3>MacBook Pro</h3>
<p>$2499</p>
<button>Add to Cart</button>
</div>
<!-- ... And also 28 more ... -->
<!-- The same code appears again in ProductList.vue, SearchResults.vue, Cart.vue -->
يضيف مدير المنتج تشارلي 5 متطلبات جديدة:
"أليس، أريد تغيير نص الزر من 'إضافة إلى سلة التسوق' إلى 'إضافة إلى الحقيبة'. كما يجب أن تعرض البطاقة status التوفر. ويجب أن يتكيف التصميم مع أجهزة الجوال."
يتعين على أليس تعديل أكثر من 30 ملف HTML ثلاث مرات = 90 تعديلاً. ومن المستحيل الحفاظ على هذا الوضع.
(2) حل مكونات Vue: ملف ProductCard.vue واحد، أعيد استخدامه 30 مرة
1 ProductCard.vue → أُعيد استخدامه 30 مرة. لتغيير نص الزر، ما عليك سوى إجراء التغيير في مكان واحد فقط.
(3) الإيرادات
بعد تقسيم النظام إلى مكونات:
- حجم الكود: 30 × 15 سطراً × 3 صفحات = 1350 سطراً → مكون واحد + 30 سطراً × 3 = 90 سطراً (-93%)
- تغيير واحد: يتم تحديث 30 بطاقة منتج تلقائيًا
- إضافة ميزة جديدة: أضفها إلى المكون، وستظهر تلقائيًا في جميع الصفحات
- قابلية الاختبار: يمكن اختبار ملف ProductCard.vue بشكل مستقل
3. ما المقصود بالمكون؟
(1) التعريف
المكون في Vue هو وحدة واجهة مستخدم قابلة لإعادة الاستخدام لها منطقها الخاص وأسلوبها التصميمي. يتكون كل مكون من مثيل واحد لـ Vue بالإضافة إلى بياناته وأساليبه ودورة حياته الخاصة.
graph TB
A[App.vue<br/>Root Component] --> B[HomeView.vue<br/>Home]
A --> C[AboutView.vue<br/>About]
A --> D[DashboardView.vue<br/>Dashboard]
B --> E[ProductCard.vue<br/>Product Card]
B --> F[ProductList.vue<br/>Product List]
B --> G[FilterBar.vue<br/>Filter Bar]
E --> H[Button.vue<br/>Button]
E --> I[Badge.vue<br/>Badge]
F --> E
G --> J[Select.vue<br/>Scroll down]
G --> K[Input.vue<br/>Input]
style A fill:#42b883,color:#fff
style E fill:#42b883,color:#fff
style H fill:#42b883,color:#fff
(2) 5 ميزات رئيسية
| الميزة | الوصف |
|---|---|
| قابل لإعادة الاستخدام | يمكن استخدام مكون واحد في N أماكن |
| التغليف | فصل البيانات والأساليب والأسلوب بحيث لا تتداخل فيما بينها |
| نظام المكونات | مكونات أصغر تُجمع معًا لتشكيل مكونات أكبر |
| قابل للاختبار | اختبار الوحدة لمكون واحد |
| قابلية الصيانة | تغيير مكان واحد = تغيير N أماكن |
(3) المكونات مقابل الوظائف
| البعد | الوظيفة | المكون |
|---|---|---|
| المكونات القابلة لإعادة الاستخدام | منطق البرمجة | واجهة المستخدم + المنطق |
| المدخلات | الحجج (args) | الخصائص (props) |
| الإخراج | الإرجاع | الإرسال |
| الstatus | المتغيرات المحلية | البيانات / المراجع |
| الآثار الجانبية | لا شيء | ربطات دورة الحياة |
4. مكون ملف واحد (SFC)
(1) ما هو SFC؟
SFC (مكون ملف واحد) = ملف .vue واحد = مكون واحد. إن دمج الأقسام template وscript وstyle في ملف واحد يسهل عملية إدارتها.
(2) شرح مفصل للجزء الثالث من قانون الأوراق المالية والبورصات (SFC)
| القسم | الوظيفة | هل هي مطلوبة؟ | اللغة |
|---|---|---|---|
<template> |
قالب HTML | ✅ | أمر HTML + Vue |
<script setup> |
JS Logic | ✅ | JavaScript / TypeScript |
<style scoped> |
أنماط CSS | ❌ | CSS / SCSS / Less |
(3) سلسلة SFC مقابل سلسلة HTML
// ❌ No need SFC(String Templates,Vue 2 Style)
Vue.component('my-component', {
template: '<div>{{ msg }}</div>',
data() { return { msg: 'Hello' } }
})
// ✅ Use SFC (Recommended)
// MyComponent.vue
<template>
<div>{{ msg }}</div>
</template>
<script setup>
const msg = 'Hello'
</script>
مزايا SFC:
- دعم المحرر (تمييز بناء الجملة، التنقل، الإكمال التلقائي)
- دعم سلسلة الأدوات (إعادة التحميل السريع في Vite، والتحقق من أنواع البيانات في TypeScript)
- فصل الاهتمامات (كتلة واحدة لكل من HTML وJS وCSS)
▶ مثال: مكون ProductCard.vue المكون من ملف واحد
▶ جرّب الكودالإخراج:
بطاقة تعرض صورة المنتج واسمه وسعره
stock = 5 → Only 5 left والزر مفعّل
stock = 0 → Out of Stock والزر معطّل
بعد النقر: emit add-to-cart بمعرّف المنتج
5. تسجيل المكونات
(1) التسجيل الشامل (لا يُنصح به للمشاريع الكبيرة)
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import ProductCard from './components/ProductCard.vue'
const app = createApp(App)
// Global Registration:All components are available <ProductCard />
app.component('ProductCard', ProductCard)
app.mount('#app')
(2) التسجيل المحلي (موصى به)
<!-- HomeView.vue -->
<script setup>
// 1. Import
import ProductCard from '@/components/ProductCard.vue'
// 2. Use in a template(No registration required,Automatically Available)
</script>
<template>
<ProductCard :product="product" />
</template>
(3) مقارنة بين طريقتي التسجيل
| البعد | التسجيل العالمي | التسجيل المحلي |
|---|---|---|
| النطاق | التطبيق بأكمله | المكون الحالي |
| موقع الرمز | main.js |
داخل المكون <script setup> |
| تغيير هيكل الشجرة | ❌ غير مدعوم | ✅ مدعوم |
| تلميحات الأنواع | ضعيفة | قوية (الإكمال التلقائي في IDE) |
| التوصية | ⭐⭐ للمكونات الإضافية | ⭐⭐⭐⭐⭐ للاستخدام التجاري |
▶ مثال: مقارنة بين التسجيل العالمي والتسجيل المحلي
// ❌ main.js Global Registration(Not recommended)
import ProductCard from './components/ProductCard.vue'
app.component('ProductCard', ProductCard) // The entire app is available
// ✅ HomeView.vue Local Registration(Recommendations)
<script setup>
import ProductCard from '@/components/ProductCard.vue'
// Only at HomeView.vue Available in China
</script>
الإخراج:
التسجيل العالمي: ProductCard متاح في كل القوالب
التسجيل المحلي: متاح داخل HomeView فقط
حجم الحزمة أصغر مع التسجيل المحلي
6. قواعد تسمية المكونات
(1) 3 قواعد تسمية
| النمط | المثال | الاستخدام | التوصية |
|---|---|---|---|
| PascalCase | ProductCard.vue |
استيراد JS / في القوالب | ⭐⭐⭐⭐⭐ |
| kebab-case | product-card.vue |
أسماء الملفات / قوالب kebab-case | ⭐⭐⭐ |
| camelCase | productCard.vue |
غير موصى به | ⭐ |
(2) الاستخدام في القوالب
(3) هيكل المجلدات
src/
├-- components/ # Public Components(For use across pages)
│ ├-- ProductCard.vue
│ ├-- Button.vue
│ └-- Header.vue
├-- views/ # Page Components(For routing)
│ ├-- HomeView.vue
│ ├-- ProductListView.vue
│ └-- DashboardView.vue
├-- composables/ # Composite Functions
│ ├-- useAuth.ts
│ └-- useFetch.ts
├-- router/ # Router Configuration
└-- App.vue # Root Component
7. أساسيات props و emit
(1) العناصر المساعدة: تنتقل من العنصر الأصلي إلى العنصر التابع
(2) الإرسال: من العنصر الفرعي إلى العنصر الأصلي
(3) دليل مرجعي سريع: props مقابل emit
| الفئة | واجهة برمجة التطبيقات (API) | الغرض |
|---|---|---|
| الأصل → الفرع | defineProps() |
نقل البيانات |
| الطفل → الوالد | defineEmits() |
إخطار بالحدث |
▶ مثال: الأنواع الخمسة الرئيسية للأدوات المسرحية
<script setup>
defineProps({
// Basic Types
name: String,
age: Number,
active: Boolean,
// Complex Types
user: Object,
items: Array,
// Required + Default value
title: { type: String, required: true },
pageSize: { type: Number, default: 20 },
// Validator
email: {
type: String,
validator: (val) => val.includes('@')
},
// Custom Types
status: {
type: String,
validator: (val) => ['active', 'inactive'].includes(val)
}
})
</script>
الإخراج:
props تُعرّف بـ String و Number و Boolean و Object و Array
title مطلوب و pageSize افتراضي 20
validator يرفض بريدًا بلا @
status يقبل active أو inactive فقط
(1) 📊 5. 5 مبادئ تصميم المكونات
| المبدأ | الوصف |
|---|---|
| المسؤولية الواحدة | كل مكون يقوم بمهمة واحدة |
| قابل لإعادة الاستخدام | واجهة مستخدم مجردة وعامة (أزرار/حقول إدخال/نوافذ منبثقة) |
| قابل للتكوين | تتحكم الخصائص (props) في السلوك، بينما تتحكم الفتحات (slots) في المحتوى |
| نظام المكونات | مكونات أصغر تُجمع معًا لتشكيل مكونات أكبر |
| سهولة الاختبار | المكونات المستقلة تجعل اختبار الوحدات أمرًا سهلاً |
(2) 📊 6. 5 أخطاء شائعة
| الخطأ | الأعراض | الحل |
|---|---|---|
| ملف قائمة المكونات | خطأ في بيئة التطوير المتكاملة | استخدم أسلوب PascalCase: ProductCard.vue |
| عدد كبير جدًا من التسجيلات العالمية | حجم حزمة أكبر | التسجيلات المحلية تدعم ميزة «tree-shaking» |
| المكون كبير جدًّا | يصعب صيانته | قسّمه إلى مكونات أصغر |
| تعديل الخصائص مباشرةً | تحذير من Vue | الخصائص مخصصة للقراءة فقط؛ استخدم emit بدلاً من ذلك |
| نسيت استيراد مكون | القالب يعرض عبارة "مكون غير معروف" | تحقق من عملية الاستيراد في <script setup> |
8. تمرين شامل: إعادة استخدام ProductCard في ثلاث صفحات
▶ مثال: إعادة استخدام «ProductCard» في 3 صفحات
<!-- src/views/HomeView.vue -->
<template>
<h1>Featured Products</h1>
<div class="grid">
<ProductCard
v-for="product in featured"
:key="product.id"
:product="product"
@add-to-cart="handleAdd"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import ProductCard from '@/components/ProductCard.vue'
import { useCart } from '@/composables/useCart'
const featured = ref([
{ id: 1, name: 'iPhone 15 Pro', price: 999, stock: 50, image: 'iphone.jpg' },
{ id: 2, name: 'MacBook Pro', price: 2499, stock: 20, image: 'macbook.jpg' }
])
const { addToCart } = useCart()
function handleAdd(productId) {
addToCart(productId)
}
</script>
<!-- src/views/ProductListView.vue -->
<template>
<ProductCard
v-for="product in products"
:key="product.id"
:product="product"
@add-to-cart="handleAdd"
/>
</template>
<script setup>
import ProductCard from '@/components/ProductCard.vue'
// ... Exactly the same citation,Reusable Components
</script>
الإخراج:
HomeView يعرض بطاقتين من featured
ProductListView يعرض البطاقة نفسها بلا تكرار كود
النقر يمرّر add-to-cart إلى handleAdd
❓ أسئلة شائعة
<el-button> من Element Plus)؛ (2) المكونات الأساسية المستخدمة في جميع أنحاء التطبيق (الأزرار/الأيقونات). أما المكونات التجارية فيجب تسجيلها محليًّا دائمًا حتى تصبح عملية «تصفية الشجرة» سارية المفعول.<template> و<script> مطلوبان؛ أما <style> فهو اختياري. إذا كان المكون يتألف من لغة JavaScript فقط (على سبيل المثال، إذا كان مخصصًا لتغليف البيانات فقط)، فيمكن حذف القالب (باستخدام الدالة render) بدلاً من ذلك.mount(ProductCard, { props: { product: mockProduct } }). تتناول المرحلة 4.6 من هذا الدليل هذا الموضوع بالتفصيل.<el-button> مباشرةً في قوالبك. لمزيد من التفاصيل، راجع الفصل 4.7 من Phase.📖 ملخص
- المكون هو مثيل Vue قابل لإعادة الاستخدام يضم أقسام القالب والنص البرمجي والأنماط.
- يُعد SFC (ملفات .vue) النهج الموصى به في Vue 3، ويحظى بدعم جيد من قبل برامج التحرير وسلاسل الأدوات.
- التسجيل المحلي > التسجيل العام (متوافق مع تقنية "tree-shaking")
- قواعد تسمية: PascalCase (ProductCard) > kebab-case (product-card)
- الخصائص: الوالد → الولد (defineProps)، الإرسال: الولد → الوالد (defineEmits)
- مبادئ تصميم المكونات: المسؤولية الواحدة، قابلية إعادة الاستخدام، قابلية التهيئة، قابلية التجميع، قابلية الاختبار
- بنية المجلدات: components/ (المكونات المشتركة)، views/ (مكونات الصفحات)، composables/ (الدوال القابلة للتركيب)
📝 تمارين
-
أسئلة أساسية (مستوى الصعوبة: ⭐)
كتابة مكون زر
src/components/BaseButton.vue:- المعلمات:
text(سلسلة)،variant(سلسلة، 'primary'/'success'/'danger') - هناك 3 أنواع تتوافق مع 3 فئات
- إصدار حدث
click - استخدم 3 أشكال مختلفة في ملف HomeView.vue
- المعلمات:
-
مسائل متقدمة (مستوى الصعوبة: ⭐⭐)
إنشاء قائمة منتجات + نظام البطاقات:
- ProductCard.vue: بطاقة منتج واحد (الخصائص: product، الإشارة: add-to-cart)
- ProductList.vue: حاوية قائمة المنتجات (v-for + التصفية)
- App.vue: المكون الجذري؛ يقوم بتمرير البيانات والتعامل مع حدث "الإضافة إلى سلة التسوق"
- 3 ملفات و3 مكونات مستخدمة في بنية متداخلة
-
مسألة التحدي (مستوى الصعوبة: ⭐⭐⭐)
تنفيذ نظام مكونات «بطاقة المستخدم» متكامل:
- Avatar.vue: مكون الصورة الرمزية (يدعم كل من وضع عنوان URL ووضع الأحرف الأولى)
- UserCard.vue: بطاقة المستخدم (مع الصورة الرمزية)
- UserList.vue: قائمة المستخدمين (باستخدام UserCard)
- App.vue: المكون الجذري (البيانات + التفاعل)
- 5 خصائص (الصورة الرمزية/الاسم/البريد الإلكتروني/الدور/status النشاط)
- 3 أحداث (تحرير/حذف/تحديد)
- عزل الأنماط المحددة النطاق