Vue.js للمبتدئين الدرس 8: المكونات

اليوم ، في الدرس الثامن من دورة Vue ، ستتعرف على المكونات لأول مرة. المكونات عبارة عن كتل من التعليمات البرمجية يمكن إعادة استخدامها ويمكن أن تتضمن كلاً من الشكل والمظهر لأجزاء من التطبيق وتنفيذ إمكانات المشروع. فهي تساعد المبرمجين على إنشاء قاعدة بيانات معيارية يسهل صيانتها. Vue.js للمبتدئين الدرس 1: Vue InstanceVue.js للمبتدئين ، الدرس 2: ربط السمةVue.js للمبتدئين ، الدرس 3: العرض الشرطيVue.js للمبتدئين ، الدرس 4: عرض القوائمVue .js للمبتدئين ، الدرس 5: معالجة الأحداثVue.js للمبتدئين ، الدرس 6: فئات وأنماط الربط



















Vue.js للمبتدئين الدرس 7: الخصائص المحسوبة

Vue.js للمبتدئين الدرس 8: المكونات



الغرض من الدرس



الهدف الرئيسي من هذا الدرس هو إنشاء مكوننا الأول واستكشاف آليات تمرير البيانات إلى المكونات.



الكود الأولي



إليك الكود الخاص بالملف index.htmlفي العلامة <body>التي سنبدأ بها:



<div id="app">
  <div class="product">
    <div class="product-image">
      <img :src="image" />
    </div>

    <div class="product-info">
      <h1>{{ title }}</h1>
      <p v-if="inStock">In stock</p>
      <p v-else>Out of Stock</p>
      <p>Shipping: {{ shipping }}</p>

      <ul>
        <li v-for="detail in details">{{ detail }}</li>
      </ul>
      <div
        class="color-box"
        v-for="(variant, index) in variants"
        :key="variant.variantId"
        :style="{ backgroundColor: variant.variantColor }"
        @mouseover="updateProduct(index)"
      ></div>

      <button
        v-on:click="addToCart"
        :disabled="!inStock"
        :class="{ disabledButton: !inStock }"
      >
        Add to cart
      </button>

      <div class="cart">
        <p>Cart({{ cart }})</p>
      </div>
    </div>
  </div>
</div>


ها هو الكود main.js:



var app = new Vue({
  el: '#app',
  data: {
    product: 'Socks',
    brand: 'Vue Mastery',
    selectedVariant: 0,
    details: ['80% cotton', '20% polyester', 'Gender-neutral'],
    variants: [
      {
        variantId: 2234,
        variantColor: 'green',
        variantImage: './assets/vmSocks-green.jpg',
        variantQuantity: 10
      },
      {
        variantId: 2235,
        variantColor: 'blue',
        variantImage: './assets/vmSocks-blue.jpg',
        variantQuantity: 0
      }
    ],
    cart: 0,
  },
  methods: {
    addToCart() {
      this.cart += 1;
    },
    updateProduct(index) {
      this.selectedVariant = index;
      console.log(index);
    }
  },
  computed: {
    title() {
      return this.brand + ' ' + this.product;
    },
    image() {
      return this.variants[this.selectedVariant].variantImage;
    },
    inStock(){
      return this.variants[this.selectedVariant].variantQuantity;
    }
  }
})


مهمة



لا نحتاج إلى تحديد موقع جميع البيانات والأساليب والخصائص المحسوبة في تطبيق Vue في مثيل الجذر Vue. بمرور الوقت ، سيؤدي ذلك إلى رمز سيكون من الصعب جدًا الحفاظ عليه. بدلاً من ذلك ، نود تقسيم الكود إلى أجزاء معيارية يسهل العمل معها وتجعل التطوير أكثر مرونة.



حل المشكلة



لنبدأ بأخذ الكود الموجود ونقله إلى مكون جديد.



هكذا main.jsيتم تسجيل المكون في الملف :



Vue.component('product', {})


الوسيطة الأولى هي اسم المكون الذي اخترناه. والثاني هو كائن خيارات مشابه للكائن الذي استخدمناه لإنشاء مثيل Vue في البرامج التعليمية السابقة.



في مثال Vue ، استخدمنا خاصية elلتنظيم ارتباطها بعنصر DOM. في حالة المكون ، يتم استخدام خاصية templateتحدد كود HTML الخاص بالمكون.



دعنا نصف قالب المكون في كائن بالخيارات:



Vue.component('product', {
  template: `
    <div class="product">
… //    HTML-,        product
    </div>
  `
})


هناك عدة طرق لإنشاء قوالب في Vue. نحن الآن نستخدم نموذجًا حرفيًا ، يتم تضمين محتوياته بين علامتي اقتباس في الخلف.



إذا اتضح أنه لن يتم وضع رمز القالب في عنصر جذر واحد ، مثل عنصر <div>به فئة product، فسيؤدي ذلك إلى ظهور رسالة الخطأ التالية:



Component template should contain exactly one root element


بمعنى آخر ، يمكن لقالب المكون إرجاع عنصر واحد فقط.



على سبيل المثال ، القالب التالي منسق بشكل جيد لأنه ممثل بعنصر واحد فقط:



Vue.component('product', {
  template: `<h1>I'm a single element!</h1>`
})


ولكن إذا كان القالب يحتوي على عدة أشقاء ، فلن يعمل. هذا مثال على نمط سيء:



Vue.component('product', {
  template: `
    <h1>I'm a single element!</h1>
    <h2>Not anymore</h2>
    `
})


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



الآن بعد أن احتوى القالب على كود HTML الذي كان موجودًا في الملف index.html، يمكننا إضافة بيانات وطرق وخصائص محسوبة إلى المكون الذي كان سابقًا في مثيل root Vue:



Vue.component('product', {
  template: `
  <div class="product">
…
  </div>
  `,
  data() {
    return {
      //   
    }
  },
    methods: {
      //   
    },
    computed: {
      //    
    }
})


كما ترى ، فإن بنية هذا المكون هي تقريبًا نفس بنية مثيل Vue الذي عملنا معه سابقًا. هل لاحظت أن dataهذه ليست خاصية الآن ، ولكنها طريقة لكائن مع خيارات؟ لماذا هو كذلك؟



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



الآن بعد أن قمنا بنقل الكود المتعلق بالمنتج إلى مكون أصلي product، تبدو الكود الخاص بوصف مثيل الجذر Vue كما يلي:



var app = new Vue({
  el: '#app'
})


الآن نحتاج فقط إلى وضع المكون productفي كود الملف index.html. سيبدو مثل هذا:



<div id="app">
  <product></product>
</div>


إذا قمت بإعادة تحميل صفحة التطبيق الآن ، فسوف تعود إلى شكلها السابق.





صفحة التطبيق



إذا نظرت الآن في أدوات مطور Vue ، فستلاحظ وجود كيان جذر ومكون منتج.





تحليل تطبيق باستخدام Vue Developer Tools



الآن ، فقط لتوضيح إمكانية إعادة استخدام المكونات ، دعنا نضيفindex.htmlبعض المكوناتالإضافية إلى الكودproduct. في الواقع ، هذه هي الطريقة التي يتم بها تنظيم إعادة استخدام المكونات. index.htmlسيبدوالرمزكما يلي:



<div id="app">
  <product></product>
  <product></product>
  <product></product>
</div>


وستعرض الصفحة ثلاث نسخ من بطاقة المنتج.





يتم عرض العديد من بطاقات المنتجات في صفحة واحدة ،



يرجى ملاحظة أننا سنعمل في المستقبل مع مكون واحدproduct، لذلكindex.htmlسيبدوالرمزكما يلي:



<div id="app">
  <product></product>
</div>


مهمة



غالبًا ما تحتاج التطبيقات إلى مكونات لقبول البيانات ومعلمات الإدخال من الكيانات الرئيسية. في هذه الحالة ، يكون أصل المكون productهو مثيل الجذر Vue نفسه.



دع مثيل root Vue يحتوي على وصف لبعض البيانات. تشير هذه البيانات إلى ما إذا كان المستخدم صاحب حساب ممتاز. قد يبدو رمز وصف مثيل Vue بالشكل التالي:



var app = new Vue({
  el: '#app',
  data: {
    premium: true
  }
})


دعنا نقرر أنه يحق للمستخدمين المميزين الحصول على شحن مجاني.



هذا يعني أننا نريد أن يقوم المكون productبإخراج premiumمعلومات تكلفة شحن مختلفة اعتمادًا على ما هو مكتوب في خاصية مثيل الجذر Vue.



كيف يمكنني إرسال البيانات المخزنة في خاصية premiumمثيل root Vue إلى الطفل وهو المكون product؟



حل المشكلة



في Vue ، لنقل البيانات من الكيانات الأصلية إلى propsالعناصر الفرعية ، يتم استخدام خاصية كائن مع الخيارات الموضحة بواسطة المكونات. هذا كائن يصف معلمات الإدخال للمكون ، والتي يجب تعيين قيمها بناءً على البيانات الواردة من الكيان الرئيسي.



لنبدأ بوصف نوع معلمات الإدخال التي يتوقع المكون تلقيها product. للقيام بذلك ، أضف الخاصية المقابلة إلى الكائن بالخيارات المستخدمة عند إنشائه:



Vue.component('product', {
  props: {
    premium: {
      type: Boolean,
      required: true
    }
  },
  //    , ,  
})


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



بعد ذلك ، دعنا نجري تغييرًا على القالب الذي يعرض المعلمات التي تم تمريرها إلى الكائن. من خلال عرض قيمة الخاصية premiumعلى الصفحة ، سنتأكد من أن الآلية التي نتحرى عنها تعمل بشكل صحيح.



<p>User is premium: {{ premium }}</p>


حتى الآن ، كل شيء يسير على ما يرام. productيعرف المكون أنه سيتلقى معلمة النوع المطلوبة لتشغيله Boolean. لقد قمنا بإعداد مكان لعرض البيانات ذات الصلة.



لكننا لم نمرر المعلمة إلى premiumالمكون حتى الآن . يمكنك القيام بذلك باستخدام سمة مخصصة تشبه "السطر" الذي يؤدي إلى مكون يمكن من خلاله نقل معلمات الإدخال ، وعلى وجه الخصوص premium.



دعنا نعدل الكود في index.html:



<div id="app">
  <product :premium="premium"></product>
</div>


لنقم بتحديث الصفحة.





إخراج البيانات التي تم تمريرها إلى المكون



يتم الآن تمرير معلمات الإدخال إلى المكون. دعنا نتحدث بالضبط عما فعلناه للتو.



نقوم بتمرير المكون إلى معلمة إدخال ، أو تسمى "سمة مخصصة"premium. نربط هذه السمة المخصصة باستخدام بنية القولون بخاصيةpremiumمخزنة في بيانات مثيل Vue الخاصة بنا.



الآن يمكن أن ينتقل مثيل root Vue إلىpremiumالمكون الفرعيproduct. نظرًا لأن السمة مرتبطة بخاصيةpremiumمن بيانات مثيل Vue ،premiumسيتم دائمًا تمريرالقيمة الحاليةإلى المكونproduct.



يوضح الشكل أعلاه ، أي النقشUser is premium: true، أن كل شيء تم بشكل صحيح.



لقد تحققنا الآن من أن آلية نقل البيانات التي ندرسها تعمل كما هو متوقع. إذا نظرت إلى أدوات مطور Vue ، فقد تبين أن المكون Productيحتوي الآن على معلمة إدخال premiumتخزن قيمة true.





معلمة الإدخال للمكون



الآن بعد أن دخلت البيانات حول ما إذا كان المستخدم لديه حساب مميز في المكون ، فلنستخدم هذه البيانات لعرض معلومات تكلفة الشحن على الصفحة. دعونا لا ننسى أنه إذا تمpremiumتعيينالمعلمةعلى قيمةtrue، فيحق للمستخدم الشحن المجاني. دعونا ننشئ خاصية محسوبة جديدةshippingونستخدم المعلمة فيهاpremium:



shipping() {
  if (this.premium) {
    return "Free";
  } else {
    return 2.99
  }
}


إذا this.premiumالمخزنة في معلمة true، الخاصية المحسوبة shippingسيعود Free. وإلا فإنه سيعود 2.99.



دعنا نزيل كود إخراج قيمة المعلمة من قالب المكون premium. الآن العنصر <p>Shipping: {{ shipping }}</p>الذي كان موجودًا في الكود الذي بدأنا به اليوم سيكون قادرًا على عرض معلومات حول تكلفة الشحن.





يحصل المستخدمون المتميزون على



نص تسليم مجانيShipping: Free يظهر على الصفحة نظرًا لحقيقة أن المكون يتم إرسال معلمة إدخالpremiumمضبوطة على قيمةtrue.



رائع! لقد تعلمنا الآن كيفية نقل البيانات من الكيانات الأم إلى الأطفال وتمكنا من استخدام هذه البيانات في المكون لإدارة تكلفة شحن البضائع.



بالمناسبة ، تجدر الإشارة إلى أنه لا يجب تغيير معلمات الإدخال الخاصة بهم في المكونات الفرعية.



ورشة عمل



أنشئ مكونًا جديدًا product-detailsيجب أن يستخدم معلمة إدخال detailsويكون مسؤولاً عن عرض جزء بطاقة المنتج الذي تم تكوينه مسبقًا باستخدام الكود التالي:



<ul>
  <li v-for="detail in details">{{ detail }}</li>
</ul>


إليك نموذج يمكنك استخدامه لحل هذه المشكلة.



هذا هو الحل للمشكلة.



النتيجة



كان اليوم أول مقدمة لك عن مكونات Vue. هذا ما تعلمته:



  • المكونات عبارة عن كتل من التعليمات البرمجية يتم تقديمها كعناصر مخصصة.
  • تجعل المكونات تطبيقك أسهل في الإدارة عن طريق تقسيمه إلى أجزاء قابلة لإعادة الاستخدام. تحتوي على أوصاف للمكون المرئي ووظائف الجزء المقابل من التطبيق.
  • يتم تمثيل بيانات المكون بواسطة طريقة data()كائن مع خيارات.
  • تُستخدم معلمات الإدخال ( props) لتمرير البيانات من الكيانات الرئيسية إلى الكيانات الفرعية .
  • يمكننا وصف متطلبات معلمات الإدخال التي يأخذها المكون.
  • .
  • .
  • Vue .




هل تستخدم أدوات مطور Vue؟



درس المبتدئين Vue.js 1: المثال Vue

Vue.js للمبتدئين ، الدرس 2: سمات الربط

Vue.js الدرس 3: العرض الشرطي

Vue.js للمبتدئين الدرس 4: عرض القوائم

Vue .js للمبتدئين الدرس الخامس: معالجة الأحداث

Vue.js للمبتدئين الدرس 6: فئات وأنماط الربط

Vue.js للمبتدئين الدرس 7: الخصائص المحسوبة

مبتدئين Vue.js الدرس 8: المكونات






All Articles