تبدیل عناصر مختلف به یکدیگر با انیمیشن

ساخت وبلاگ
Vue.JS 2: <strong>تبدیل</strong> <strong>عناصر</strong> <strong>مختلف</strong> به <strong>یکدیگر</strong> با <strong>انیمیشن</strong> - قسمت 62

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

برای شروع این جلسه به فایل App.vue رفته و از transition دارای alertAnimation یک کپی بگیرید. همچنین به قسمت style ها رفته مدت زمان transition را در slide-leave-active از سه ثانیه به یک ثانیه تغییر دهید تا همه چیز مرتب و بدون مشکل باشد:

سپس برای transition:

حالا مجموعا چهار transition داریم. برای اینکه بتوانیم با انیمیشن دو عنصر را به یکدیگر تبدیل کنیم حداقل به دو عنصر نیاز داریم بنابراین در transition تازه کپی شده یک div دیگر ایجاد می کنیم:

همانطور که مشاهده می کنید ما دو div مختلف درون این transition داریم: اولی، کلاس info و دومی، کلاس warning دارد. قبلاً هم توضیح داده بودم که درون transition ها فقط یک عنصر با یک شرط جا می گیرد و اگر بخواهیم چند عنصر را درون یک transition داشته باشیم باید شرط آن ها با هم یکی نباشد (در ادامه دوره، راه حل استفاده از transition برای چندین عنصر با یک شرط واحد را نیز توضیح می دهیم اما فعلاً بحث ما مربوط به این موضوع نیست) به همین دلیل شرط div دوم را برعکس شرط اول گذاشته ام.

نکته: کد بالا با v-show کار نمی کند چرا که v-show عنصر را از DOM حذف نکرده و فقط آن را با display: none مخفی می کند. در این صورت باز هم دو عنصر درون transition خواهیم داشت و باعث خطا می شویم.

البته برای زیبا تر شدن کدها می توانیم به جای دو v-if، از v-else نیز استفاده کنیم:

شاید تصور کنید که با باز کردن مرورگر همه چیز حل می شود اما اینطور نیست. در حال حاضر دو کادر ما به هم تبدیل می شوند اما هیچ fade یا انیمیشن دیگری مشخص نیست و تبدیل شدن آن ها به صورت آنی انجام می شود. دلیل این مشکل چیست؟ اگر برای چنین شرایطی از یک عنصر دو بار استفاده کنیم (مثل کد بالا که دو div داریم) Vue نمی تواند بین آن ها تفاوت قائل شود. از نظر Vue هر دو div در کد بالا یکی هستند بنابراین فقط محتوای آن ها را با هم عوض می کند و طبیعتا انیمیشنی نمایش داده نمی شود. برای این که کلاس های انیمیشن به صورت صحیح روی عناصر اعمال شوند، باید خود عناصر تغییر کنند نه محتوایشان.

 برای حل این مشکل باید برای هر کدام از این دیوها key (به معنی کلید) تعریف کنیم. این key شناسنامه این دیوها است و مشخص می کند که این دو با یکدیگر تفاوت دارند:

اگر کدهای بالا را ذخیره کرده و به مرورگر بروید شاهد مشکل دیگری خواهید بود. مشکل جدید این است که کادر دوم، قبل از حذف شدن کادر اول به صفحه اضافه می شود و به همین دلیل شاهد یک جهش بین این دو کار هستیم. این جهش باعث می شود ظاهر برنامه بسیار زشت شود.

اگر این دو عنصر را position: absolute تعریف کرده بودیم هر دو عنصر روی یکدیگر قرار می گرفتند و دیگر شاهد این جهش نبودیم اما ما نمی خواهیم position کادرهای خود را تغییر دهیم. با این حساب راه حل چیست؟ فریم ورک Vue برای این مسئله راه حلی را در نظر گرفته است؛ ما باید mode یا حالت transition را تغییر دهیم. ما دو مقدار برای خصوصیت mode داریم:

  • out-in: این گزینه به Vue می گوید بگذار ابتدا عنصر قبلی کاملا حذف شود و سپس به عنصر بعدی اجازه نمایش بده.
  • in-out: این گزینه به Vue می گوید ابتدا عنصر جدید را نمایش بده و سپس عنصر قبلی را حذف کن.

برای کاری که ما می خواهیم انجام دهیم، out-in مشکل را حل می کند:

حالا اگر مرورگر را باز کنید (npm run dev در حال اجرا باشد) می بینید که کادر آخر با کلیک روی دکمه Show Alert بین info و warning جا به جا می شود.

تا این قسمت از کار از CSS برای ایجاد انیمیشن استفاده کرده ایم اما می خواهم بدانید که می توانیم با جاوا اسکریپت نیز این کارها را انجام بدهیم. در واقع کامپوننت <transition> که تا به حال با آن کار کرده ایم، دارای event هایی است که می توانیم به آن ها گوش کنیم. این event ها به شکل زیر هستند:

  • در حالت اولیه پس از اضافه شدن عنصر به DOM رویدادی به نام before-enter ارسال (emit) می شود.
  • پس از آن رویداد enter ارسال (emit) می شود که مسئول نمایش انیمیشن است.
  • پس از آنکه اجرای انیمیشن تمام شد، رویداد after-enter ارسال (emit) می شود.
  • اگر قبل از تمام شدن اجرای انیمیشن، شرط نمایش آن تغییر کند و انیمیشن کنسل شود، رویداد after-enter-cancelled ارسال می شود.
  • در هنگام شروع عملیات حذف عنصر از DOM رویداد before-leave ارسال می شود.
  • در هنگام اجرای انیمیشن حذف عنصر، رویداد leave ارسال می شود.
  • پس از اتمام انیمیشن حذف، رویداد after-leave ارسال می شود.
  • اگر انیمیشن حذف یا خروج به دلیلی کنسل شود، رویداد after-leave-cancelled اجرا خواهد شد.

به این رویدادها Transition JS Hook می گوییم، یعنی هوک هایی جاوا اسکریپتی که به transition مربوط هستند. در جلسه بعد به صورت عملی با آن ها کار خواهیم کرد.

کارت ویزیت لایه باز...
ما را در سایت کارت ویزیت لایه باز دنبال می کنید

برچسب : نویسنده : graphiao بازدید : 63 تاريخ : جمعه 16 آبان 1399 ساعت: 9:36