تا این قسمت از کار یکی از عناصر را با انیمیشن ظاهر کرده و سپس همان را خارج می کردیم اما در بسیاری از اوقات می خواهیم کار دیگری را انجام بدهیم. در بسیاری از اوقات لازم است که هم زمان با مخفی شدن یک عنصر، عنصر دیگری ظاهر شود. به عبارت دیگر به جای تعریف انیمیشن برای حذف یا نمایش عنصر، نیاز به تعریف انیمیشن برای تبدیل عناصر به یکدیگر داریم.
برای شروع این جلسه به فایل App.vue رفته و از transition دارای alertAnimation یک کپی بگیرید. همچنین به قسمت style ها رفته مدت زمان transition را در slide-leave-active از سه ثانیه به یک ثانیه تغییر دهید تا همه چیز مرتب و بدون مشکل باشد:
.slide-leave-active { animation: slide-out 1s ease-out forwards; transition: opacity 1s; opacity: 0; }
سپس برای transition:
<transition :name="alertAnimation"> <div class="alert alert-info" v-if="show">This is some Info</div> </transition> <transition name="slide" type="animation"> <div class="alert alert-info" v-if="show">This is some Info</div> </transition> <transition appear enter-active-class="animated bounce" leave-active-class="animated shake"> <div class="alert alert-info" v-if="show">This is some Info</div> </transition> <transition :name="alertAnimation"> <div class="alert alert-info" v-if="show">This is some Info</div> </transition>
حالا مجموعا چهار transition داریم. برای اینکه بتوانیم با انیمیشن دو عنصر را به یکدیگر تبدیل کنیم حداقل به دو عنصر نیاز داریم بنابراین در transition تازه کپی شده یک div دیگر ایجاد می کنیم:
<transition :name="alertAnimation"> <div class="alert alert-info" v-if="show">This is some Info</div> <div class="alert alert-warning" v-if="!show">This is some Warning</div> </transition>
همانطور که مشاهده می کنید ما دو div مختلف درون این transition داریم: اولی، کلاس info و دومی، کلاس warning دارد. قبلاً هم توضیح داده بودم که درون transition ها فقط یک عنصر با یک شرط جا می گیرد و اگر بخواهیم چند عنصر را درون یک transition داشته باشیم باید شرط آن ها با هم یکی نباشد (در ادامه دوره، راه حل استفاده از transition برای چندین عنصر با یک شرط واحد را نیز توضیح می دهیم اما فعلاً بحث ما مربوط به این موضوع نیست) به همین دلیل شرط div دوم را برعکس شرط اول گذاشته ام.
نکته: کد بالا با v-show کار نمی کند چرا که v-show عنصر را از DOM حذف نکرده و فقط آن را با display: none مخفی می کند. در این صورت باز هم دو عنصر درون transition خواهیم داشت و باعث خطا می شویم.
البته برای زیبا تر شدن کدها می توانیم به جای دو v-if، از v-else نیز استفاده کنیم:
<transition :name="alertAnimation"> <div class="alert alert-info" v-if="show">This is some Info</div> <div class="alert alert-warning" v-else>This is some Warning</div> </transition>
شاید تصور کنید که با باز کردن مرورگر همه چیز حل می شود اما اینطور نیست. در حال حاضر دو کادر ما به هم تبدیل می شوند اما هیچ fade یا انیمیشن دیگری مشخص نیست و تبدیل شدن آن ها به صورت آنی انجام می شود. دلیل این مشکل چیست؟ اگر برای چنین شرایطی از یک عنصر دو بار استفاده کنیم (مثل کد بالا که دو div داریم) Vue نمی تواند بین آن ها تفاوت قائل شود. از نظر Vue هر دو div در کد بالا یکی هستند بنابراین فقط محتوای آن ها را با هم عوض می کند و طبیعتا انیمیشنی نمایش داده نمی شود. برای این که کلاس های انیمیشن به صورت صحیح روی عناصر اعمال شوند، باید خود عناصر تغییر کنند نه محتوایشان.
برای حل این مشکل باید برای هر کدام از این دیوها key (به معنی کلید) تعریف کنیم. این key شناسنامه این دیوها است و مشخص می کند که این دو با یکدیگر تفاوت دارند:
<transition :name="alertAnimation"> <div class="alert alert-info" v-if="show" key="info">This is some Info</div> <div class="alert alert-warning" v-else key="warning">This is some Warning</div> </transition>
اگر کدهای بالا را ذخیره کرده و به مرورگر بروید شاهد مشکل دیگری خواهید بود. مشکل جدید این است که کادر دوم، قبل از حذف شدن کادر اول به صفحه اضافه می شود و به همین دلیل شاهد یک جهش بین این دو کار هستیم. این جهش باعث می شود ظاهر برنامه بسیار زشت شود.
اگر این دو عنصر را position: absolute تعریف کرده بودیم هر دو عنصر روی یکدیگر قرار می گرفتند و دیگر شاهد این جهش نبودیم اما ما نمی خواهیم position کادرهای خود را تغییر دهیم. با این حساب راه حل چیست؟ فریم ورک Vue برای این مسئله راه حلی را در نظر گرفته است؛ ما باید mode یا حالت transition را تغییر دهیم. ما دو مقدار برای خصوصیت mode داریم:
برای کاری که ما می خواهیم انجام دهیم، out-in مشکل را حل می کند:
<transition :name="alertAnimation" mode="out-in"> <div class="alert alert-info" v-if="show" key="info">This is some Info</div> <div class="alert alert-warning" v-else key="warning">This is some Warning</div> </transition>
حالا اگر مرورگر را باز کنید (npm run dev در حال اجرا باشد) می بینید که کادر آخر با کلیک روی دکمه Show Alert بین info و warning جا به جا می شود.
تا این قسمت از کار از CSS برای ایجاد انیمیشن استفاده کرده ایم اما می خواهم بدانید که می توانیم با جاوا اسکریپت نیز این کارها را انجام بدهیم. در واقع کامپوننت <transition> که تا به حال با آن کار کرده ایم، دارای event هایی است که می توانیم به آن ها گوش کنیم. این event ها به شکل زیر هستند:
به این رویدادها Transition JS Hook می گوییم، یعنی هوک هایی جاوا اسکریپتی که به transition مربوط هستند. در جلسه بعد به صورت عملی با آن ها کار خواهیم کرد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.