به قسمت آخر از این فصل خوش آمدید. در قسمت قبل کد زیر را داشتیم:
<script> import List from "./List.vue"; import { fruitMixin } from "./fruitMixin"; export default { mixins: [fruitMixin], data() { return { text: "Hello there!" }; }, filters: { toUppercase(value) { return value.toUpperCase(); } }, components: { appList: List } }; </script>
نکته جالبی که در مورد این کد وجود دارد این است که import کردن mixin ها باعث نابودی شیء Vue ما یا اطلاعات درون آن نمی شود بلکه با دقت دو مقدار را روی هم merge (ادغام) می کند. نکته بعدی اینجاست که اگر درون Mixin ها از lifecycle hook ها استفاده کنید و سپس درون شیء Vue نیز از lifecycle hook دیگری استفاده کنید، هر دو اجرا می شوند حتی اگر همنام باشند! ترتیب اجرا شدنشان نیز بدین صورت است:
بگذارید با یک مثال این مسئله را برایتان روشن کنم. من به فایل fruitMixin.js می روم و از lifecycle hook ای به نام Created استفاده می کنم:
export const fruitMixin = { data() { return { fruits: ["Apple", "Banana", "Mango", "Melon"], filterText: "" }; }, computed: { filteredFruits() { return this.fruits.filter(element => { return element.match(this.filterText); }); } }, created() { console.log('Created'); } }
برای اینکه فهم موضوع ساده باشد فقط از یک دستور log استفاده کرده ام. حالا اگر مرورگر را باز کرده و صفحه را refresh کنیم، عبارت created دو بار در قسمت کنسول نمایش داده می شود:
چرا؟ به دلیل اینکه فایل های App.vue و List.vue از این Mixin استفاده می کنند بنابراین هر دو، کدهای آن را اجرا می کنند. بیایید فرض دیگری داشته باشیم. اگر وارد فایل List.vue شده و دوباره از lifecycle hook ای به نام created استفاده کنیم چه اتفاقی می افتد؟ به کد زیر از فایل List.vue توجه کنید:
<script> import { fruitMixin } from "./fruitMixin"; export default { mixins: [fruitMixin], created() { console.log("Inside List Created Hook"); } }; </script>
مقدار log شده در این کد Inside List Created Hook است که به فارسی یعنی created ای که درون List وجود دارد. اگر این کد را ذخیره کرده و مرورگر را باز کنیم با این صحنه روبرو می شویم:
منظور من از ترتیب اجرا شدن کدها همین بود. ابتدا Mixin اجرا می شود و سپس کدهای درون component. چرا؟ به دلیل اینکه با این روش کامپوننت می تواند کدهای Mixin را overwrite کند (باطل کرده و کدهای خودش را اعمال کند) تا اگر تناقضی وجود داشت، mixin نتواند جزئیات کامپوننت ها را نابود کند.
مسئله بعدی Mixin های سراسری یا Global Mixins است. شاید یک Mixin ای داشته باشیم که بخواهیم از آن روی تک تک کامپوننت های خود استفاده کنیم. ما تقریبا هیچگاه از mixin های سراسری استفاده نمی کنیم چرا که روی همه برنامه اجرا می شوند. Documentation رسمی وب سایت Vue.js می گوید که mixin های سراسری معمولا فقط برای ساخت پلاگین برای فریم ورک Vue کاربرد دارند نه روی برنامه های واقعی. در عین حال دوست دارم نحوه ساخت آن ها را بدانید.
برای این کار ابتدا به فایل main.js رفته و می گوییم:
import Vue from 'vue' import App from './App.vue' Vue.filter('to-lowercase', function (value) { return value.toLowerCase(); }); Vue.mixin({ created() { console.log('Global Mixin - Created Hook'); } })
اگر چنین کاری بکنیم، نیازی به دستور import نیست و mixin ما به صورت خودکار به تمام کامپوننت ها اضافه می شود. حالا به مرورگر می رویم و ترتیب اجرا شدن را می بینیم:
سوال: ما دو کامپوننت داریم: App.vue و List.vue اما global mixin ما 3 بار اجرا شده است! چرا؟
پاسخ: ما درون فایل main.js یک شیء Vue دیگر را نیز داریم. دقیقا پایین تر از Mixin سراسری خودمان:
import Vue from 'vue' import App from './App.vue' Vue.filter('to-lowercase', function (value) { return value.toLowerCase(); }); Vue.mixin({ created() { console.log('Global Mixin - Created Hook'); } }) new Vue({ el: '#app', render: h => h(App) })
با این حساب بر اساس تصویر بالا از کنسول مرورگر می گوییم:
خلاصه این توضیحات به شکل زیر است:
سوال بسیار مهم: اگر data را درون mixin تغییر بدهیم چه اتفاقی می افتد؟ آیا data درون mixin بین تمام کامپوننت ها به اشتراک گذاشته می شود یا اینکه برای هر کامپوننت یک نمونه جدا از Data ساخته می شود و از هم مستقل هستند؟
پاسخ: کدهای mixin به اشتراک گذاشته نمی شود و هر کدام از کامپوننت ها یک کپی جداگانه از آن را دریافت می کنند. بنابراین اگر کدهای data را درون App.vue تغییر بدهیم، data درون List.vue تغییر نخواهد کرد. اگر بخواهید آن را به اشتراک بگذارید باید شیء خود را (مثلا اینجا فایل fruitMixin.js) به شکل عادی import کنید نه اینکه به عنوان یک mixin ثبت نمایید. همچنین استفاده از Event Bus که در جلسات قبل در موردش صحبت کردیم راه حل خوبی است.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.