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

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







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

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

Vue.js للمبتدئين ، الدرس 3: العرض الشرطي

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

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

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

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

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

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



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



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



الكود الأولي



يحتوي ملف index.htmlالمشروع النموذجي الآن على التعليمات البرمجية التالية:



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


هذا هو محتوى الملف main.js:



Vue.component('product', {
  props: {
    premium: {
      type: Boolean,
      required: true
    }
  },
  template: `
  <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>
  `,
  data() {
    return {
      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;
      },
      shipping() {
        if (this.premium) {
          return "Free";
        } else {
          return 2.99
        }
      }
    }
})

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


مهمة



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



القرار



دعنا نعيد البيانات المتعلقة بسلة التسوق إلى مثيل root Vue:



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


بعد ذلك ، دعنا نعيد قالب عربة التسوق مرة أخرى index.html، مع جلب الكود الخاص به إلى هذا النموذج:



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

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


الآن ، إذا فتحت صفحة التطبيق في متصفح ونقرت على الزر Add to cart، فلن يحدث شيء كما هو متوقع.





النقر فوق الزر "إضافة إلى عربة التسوق" لا يؤدي إلى أي شيء بعد



، فماذا يجب أن يحدث عند النقر فوق هذا الزر؟ نحتاج إلى أنه عند النقر فوقه ، سيتلقى مثيل الجذر Vue إشعارًا من شأنه استدعاء طريقة تعمل على تحديث سلة التسوق ، أي تحديث القيمة المخزنة فيهاcart.



من أجل تحقيق ذلك ، دعنا أولاً نعيد كتابة كود طريقةaddToCartالمكونproduct.



الآن يبدو مثل هذا:



addToCart() {
  this.cart += 1;
},


لنجلبه إلى هذا النموذج:



addToCart() {
  this.$emit('add-to-cart');
},


ماذا يعني كل هذا؟



هذا ما هو عليه. عندما يتم استدعاء الأسلوب addToCart، يتم إنشاء حدث مسمى مخصص add-to-cart. بمعنى آخر ، عند Add to cartالنقر فوق الزر ، يتم استدعاء طريقة تنشئ حدثًا يشير إلى أن الزر قد تم الضغط عليه للتو (أي أن الحدث الذي تم تشغيله بواسطة النقر فوق الزر قد حدث للتو).



لكن في الوقت الحالي ، لا يوجد شيء في التطبيق ينتظر حدوث هذا الحدث أو الاستماع إليه. دعنا نضيف مستمع الحدث إلى index.html:



<product :premium="premium" @add-to-cart="updateCart"></product>


هنا نستخدم بناء العرض @add-to-cardبنفس الطريقة التي نستخدم بها البناء :premium. ولكن إذا كان :premiumعبارة عن "خط أنابيب" يمكن من خلاله نقل البيانات إلى المكون الفرعي من العنصر الرئيسي ، @add-to-cartفيمكن مقارنته بـ "مستقبل الراديو" للمكون الأصلي ، والذي يتلقى معلومات من المكون الفرعي بأنه تم الضغط على زر Add to cart. نظرًا لأن "الراديو" موجود في علامة <product>متداخلة <div id="app">، فهذا يعني أنه عند وصول معلومات حول النقرة ، Add to cartسيتم استدعاء الطريقة updateCartالموجودة في مثيل الجذر Vue. عند ترجمتها إلى لغة عادية ، يبدو



الرمز @add-to-cart=«updateCart»بالشكل التالي: "عندما تسمع وقوع حدث ما add-to-cart، اتصل بالطريقة updateCart".



هذه الطريقة ، التي سيتم الإعلان عنها الآن في كائن الخيارات المستخدم عند إنشاء مثيل Vue ، ربما رأيت في مكان ما:



methods: {
  updateCart() {
    this.cart += 1;
  }
}


في الواقع ، هذه هي الطريقة نفسها التي تم استخدامها سابقًا في product. ولكنه الآن موجود في مثيل root Vue ويتم استدعاؤه بنقرة زر Add to cart.





يعمل الزر مرة أخرى



عند النقر فوق الزر الموجود في أحد المكوناتproduct، يتم استدعاء الطريقةaddToCartالتي تنشئ حدثًا. يتعلم مثيل الجذر Vue ، "الاستماع إلى الراديو" ، أن هذا الحدث قد وقع ويستدعي طريقةupdateCartتزيد الرقم المخزن فيهcart.



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



يمكن وصف البيانات التي تم تمريرها في الحدث على أنها الوسيطة الثانية التي تم تمريرها$emitفي رمز طريقةaddToCartالمكونproduct:



this.$emit('add-to-cart', this.variants[this.selectedVariant].variantId);


يمر الحدث الآن معرّف ( variantId) المنتج الذي يريد المستخدم إضافته إلى سلة التسوق. هذا يعني أنه بدلاً من مجرد زيادة عدد العناصر في سلة التسوق ، يمكننا الذهاب إلى أبعد من ذلك وتخزين معلومات أكثر تفصيلاً حول العناصر المضافة إليها في سلة التسوق. للقيام بذلك ، نقوم أولاً بتحويل السلة إلى مصفوفة عن طريق كتابة مصفوفة فارغة إلى cart:



cart: []


بعد ذلك ، دعنا نعيد كتابة الطريقة updateCart. أولاً - سيقبل الآن id- نفس معرف المنتج الذي تم تمريره الآن في الحدث ، وثانيًا - سيضع الآن ما تم استلامه في مصفوفة:



methods: {
  updateCart(id) {
    this.cart.push(id);
  }
}


بعد النقر فوق الزر مرة واحدة ، يتم إضافة معرف المنتج إلى المصفوفة. يتم عرض المصفوفة على الصفحة.





يتم عرض المصفوفة مع معرف المنتج على الصفحة



لا نحتاج إلى عرض المصفوفة بأكملها على الصفحة. سنكون راضين عن ناتج عدد المنتجات المضافة إلى سلة التسوق ، أي إلى المصفوفةcart. لذلك ، يمكننا إعادة كتابة رمز العلامة<p>، والذي يعرض معلومات حول عدد المنتجات المضافة إلى سلة التسوق ، مثل هذا:



<p>Cart({{ cart.length }})</p>




تعرض الصفحة معلومات حول عدد العناصر المضافة إلى عربة التسوق ،



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



ورشة عمل



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



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


النتيجة



هذا ما تعلمته اليوم:



  • يمكن للمكون إعلام الكيان الأصلي بحدوث شيء فيه باستخدام الإنشاء $emit.
  • يمكن للمكون الأصل استخدام معالج الحدث المحدد باستخدام التوجيه v-on(أو نسخته المختصرة @) لتنظيم الاستجابة للأحداث التي تم إنشاؤها بواسطة المكونات الفرعية. في حالة حدوث حدث ، يمكن استدعاء معالج الحدث في المكون الرئيسي.
  • , , .


إذا كنت تدرس الدورة التدريبية ووصلت إلى هذا الدرس ، فيرجى إخبارنا بالغرض الذي تقوم به ، وما الذي تريد تحقيقه من خلال إتقان Vue.



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

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

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

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

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

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

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

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

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






All Articles