جلسه نوزدهم آموزش فریم ورک vue.js : آشنایی با Bus Event در vue.js

آشنایی با Bus Event در vue.js

 

در جلسه قبلی آموزش vue.js به مبحث custom event ها پرداختیم، حال در این جلسه به آشنایی با Bus Event در vue.js می پردازیم.

Bus Event

ممکن است در پروژه ، تعداد کامپوننت هایی که به صورت زنجیروار به هم متصل باشند زیاد باشد:

یعنی هر والدی دارای چند فرزند باشد و فرزنداشون هم دارای فرزند و… به همین ترتیب این سلسه مراتب زیاد باشد.

در اینجا اگر بخواهیم برای هر فرزندی event تعریف کنیم و بفرستیم به لایه ها و کامپوننت های بالاتر به مشکل بر میخوریم، بنابراین در اینجا پای Event Bus میاد وسط.

 

نحوه پیاده سازی Bus Event

3 تا کامپوننت ، یکی والد و دو تا فرزند تعریف میکنیم به شکل زیر :

User.vue

<template>
  <div>
    <user-first ></user-first>
    <user-second ></user-second>
  </div>
</template>

<script>
import UserFirstChild from "./UserFirstChild.vue";
import UserSecondChild from "./UserSecondChild.vue";
export default {
  components: {
    "user-second": UserSecondChild,
    "user-first": UserFirstChild
  },
};
</script>

در والد یک دیتا تعریف میکنیم به نام age حالا میایم و ازش در تمپلیت والد استفاده میکنیم

و بعد داخل فرزندها به روش جلسه قبل پاس میدهیم.

کدها به شکل زیر تغییر میکند:

User.vue

<template>
  <div>
    <p>current age in parent is : {{ Age }}</p>
    <hr>
    <user-first :_age="Age"></user-first>
    <user-second :_age="Age"></user-second>
  </div>
</template>

<script>
import UserFirstChild from "./UserFirstChild.vue";
import UserSecondChild from "./UserSecondChild.vue";
export default {
  components: {
    "user-second": UserSecondChild,
    "user-first": UserFirstChild
  },
  data: function() {
    return {
      Age: 22
    };
  },
};
</script>

UserFirstChild.vue , UserSecondChild.vue

<template>
  <div class="col-md-6">
    <div class="border-child">
      <p>Age from parent is : {{ Age }}</p>
    </div>
    <div class="clearfix"></div>
  </div>
</template>

<script>
export default {
  props: {
    _age: Number
  },
  data: function() {
    return {
      Age: this._age
    };
  },
};
</script>

<style>
.border-child {
  border: 2px solid blue;
  border-radius: 5px;
  padding: 10px;
  background-color: orange;
}
</style>

حالا می آییم و یک دکمه UserSecondChild.vue میگذاریم برای تغییر مقدار age توسط فرزند در والد:
( کاری که در جلسه گذشته انجام دادیم)

<a @click="ChangeAge" class="btn btn-success">Change Age</a>

حالا یک فانکشن برای تغییر مقدار سن در UserSecondChild می نویسیم به شکل زیر:

methods: {
  ChangeAge() {
        this.Age = "30"
    }
}

تا اینجا با زدن دکمه ChangeAge میاد و مقدار سن را فقط در خود UserSecondChild تغییر میدهد، حالا میخواهیم بیاد و مقدار والد نیز عوض شود:

کد را به شکل زیر می نوشتیم:

methods: {
  ChangeAge() {
    this.Age = 30;
    this.$emit("changeAge", this.Age);
  }
}

سپس در والد آن را فراخوانی میکنیم:

<user-second :_age="Age" @changeAge="chageAge"></user-second>

changeAge@ : نامی هست که از فرزند آوردیم
chageAge”= : فانکشنی هست که در والد به شکل زیر تعریف میکنیم:

حالا در والد میایم متد changeAge رو هم تعریف میکنیم:

methods: {
  chageAge(age) {
    this.Age = age;
  }
}

چون مقداری که براش ارسال شده سن هست، می آییم و ورودی را age قرار میدهیم.
تا اینجا، مقدار age با کلیک روی دکمه changeAge در فرزند هم در خود فرزند و هم در والد تغییر میکند.

نحوه ارتباط دو کامپوننت فرزند بدون ایجاد تغییر در والد:

در مثال: میخواهیم با تغییر سن در فرزند دوم، مقدار به فرزند اول هم انتقال پیدا کند.
کاری که انجام میدهیم در صورتی که فرزندهای دیگری نیز تعریف کنیم باز در سایر فرزندها هم قابل اجراست، البته فرزندهایی که والدشون یکی هست.

برای اینکار به Bus Event احتیاج داریم:

1- ابتدا داخل main.js باید یک instance جدید از vue را به شکل زیر ایجاد کنیم:
نکته : حتما به vue امون نام میدهیم که با vue دیگر به confilict نخوریم.

این برای ما شبیه یک کلاس میتونه باشه که یکسری object داخلشه و ما میتوانیم از آنها در همه پروژه امون ازش استفاده کنیم.

export const BusEvent = new Vue();

نکته خیلی خیلی مهم :
اگر instance ای که از vue ساختیم بعد از instance اصلی داخل main.js باشد، کد اصلا اجرا نمیشود و حتما حتما باید قبل از آن باشد.

2- ما اگر برگردیم به UserSecondChild ، event امون را با this.$emit جوری تعریف کردیم که برمیگرده به فقط همین کامپوننتمون ، در حالیکه ما باید جوری آن را تعریف کنیم که در کل پروژه در دسترس باشد.

بنابراین اول باید vue ای که در main.js ساختیم را بتونیم اینجا استفاده کنیم
پس فایل main.js را در این فایل import میکنیم به شکل زیر:

import { BusEvent } from “../main.js”;

نکته : چون ما خود فایل را احتیاج نداریم فقط به BusEvent احتیاج داریم، در syntax ایکما اسکریپت با زدن space خودش BusEvent را برامون میاره.

3- حالا در فانکشن به جای this.$emit ، کد را باید به شکل زیر بنویسیم:

BusEvent.$emit("changeAge", this.Age);

4- حالا چون میخواهیم ارتباط بین دو فرزند را برقرارکنیم، باید BusEvent رو داخل فرزند اول هم import کنیم،

5- حالا نحوه استفاده از BusEvent در فرزند دیگر:
یکسری دستور داریم که یکیش ()created هست و برای اینکه بگیم بیا و زمانی که این کامپوننت ایجاد شد از BusEvent استفاده کن :
به کد زیر توجه کنید:

<script>
import { BusEvent } from "../main.js";
export default {
  props: {
    _age: Number
  },
  data: function() {
    return {
      Age: this._age
    };
  },
  created() {
    BusEvent.$on("changeAge", age => {
      this.Age = age;
    });
  }
};
</script>

نحوه تعریف و استفاده از BusEvent رو هم در بالا مشاهده میکنید که سینتکس بالا رو دارد. که میگه وقتی event با نام ChangeAge رخ داد و fire شد، مقدار ورودی که همان age هست را دریافت کن و داخلش عملیاتی که میخوای رو انجام بده.

در خروجی میبینیم که با زدن دکمه داخل فرزند دوم، مقدار سن در فرزند اول و دوم بدون اینکه والد تغییر کند، تغییرمیکند.

نکته : در پروژه های بزرگ مثل پروژه های فروشگاهی، ممکن است event ها زیاد باشد و این نحوه استفاده کار را سخت میکند،
در اینجا vue.js یک ابزار قدرتمندی را به نام vueex که بر پایه ریداکس هست را در اختیارمون قرار میدهد،

نکته : ما میتوانیم داخل بدنه vue ای که تحت عنوان BusEvent ساختیم مقادیری را کاملا مثل vue های دیگر بسازیم و ازش استفاده کنیم… میتواند شامل data و متدهایی باشد که در کل پروژه در دسترس خواهند بود.

مثال: مثلا یک متد changeAge میسازیم داخل BusEvent و به شکل زیر ازش استفاده میکنیم:

فایل main.js:

export const BusEvent = new Vue({
  methods: {
    changeAge(age) {
      this.$emit("changeAge", age);
    }
  },
  data() {
    return {
      PublicAge: 45
    };
  }
});

نحوه استفاده در UserSecondChild :

<script>
import { BusEvent } from "../main.js";
export default {
  props: {
    _age: Number
  },
  data: function() {
    return {
      Age: this._age
    };
  },
  methods: {
    ChangeAge() {
      this.Age = BusEvent.PublicAge;
      BusEvent.changeAge(BusEvent.PublicAge);
    }
  }
};
</script>

با اینکار، در خروجی با زدن روی دکمه ChangeAge در فرزند دوم، مقدار سن در فرزند اول هم تغییر میکند.

برچسب‌ها:

کامنت ها

  1. هدیه :

    اکتبر 12th, 2019 در 10:54 ق.ظ

    آموزش مفیدی بود، ممنونم

  2. مهدیه امیری :

    اکتبر 12th, 2019 در 10:58 ق.ظ

    سپاسگزارم

با کامنت گذاری ما را در ارائه آموزش بهتر یاری کنید

026-32601 داخلی 4

info@pinsite.ir

ثبت سفارش طراحی سایت

برای دریافت تخفیف، در هنگام تماس، نحوه آشنایی با شرکت را از طریق سایت pinsite.ir اعلام کنید