در قسمت قبل با hook های جاوا اسکریپتی برای ساخت انیمیشن ها آشنا شدیم و برای هر کدام متدی تعریف کردیم. در این قسمت می خواهیم کدهای جلسه قبل را تکمیل کرده و مقدمات نهایی را آماده سازی کنیم. ما تا متد enter پیش آمده بودیم و در مورد done نیز صحبت کردیم اما حالا متدهای بعدی ما afterEnter و enterCancelled هستند، بنابراین:
methods: { beforeEnter(el) { console.log("beforeEnter"); }, enter(el, done) { console.log("enter"); done(); }, afterEnter(el) { console.log("afterEnter"); }, enterCancelled(el) { console.log("enterCancelled"); } }
تا اینجا تمام متدهای enter را نوشته ایم و حالا نوبت به متدهای leave می رسد:
methods: { beforeEnter(el) { console.log("beforeEnter"); }, enter(el, done) { console.log("enter"); done(); }, afterEnter(el) { console.log("afterEnter"); }, enterCancelled(el) { console.log("enterCancelled"); }, beforeLeave(el) { console.log("beforeLeave"); }, leave(el, done) { console.log("leave"); done(); }, afterLeave(el) { console.log("afterLeave"); }, leaveCancelled(el) { console.log("leaveCancelled"); } }
در کد بالا به done در leave توجه کنید. همانطور که برای enter آن را دریافت می کردیم، برای leave نیز آن را دریافت می کنیم تا بدانیم چه زمانی می خواهیم عنصر را حذف کنیم و انیمیشن تمام شده است. اگر done را صدا نزنید، کدها با مشکل مواجه می شوند. حالا مرورگر را باز کرده و به قسمت console آن نگاه می کنیم. با کلیک روی Load / Remove Element مربع ما حذف می شود و به ترتیب سه پیام زیر را در کنسول می بینیم:
سپس اگر دوباره روی دکمه Load / Remove Element مربع ما ظاهر شده و پیام های زیر را در کنسول می بینیم:
بنابراین همه چیز به درستی کار می کند (اگر با این hook ها و ترتیب اجرای آن ها آشنایی ندارید به قسمت قبل سر بزنید). ما فعلا نمی توانیم هوک های cancel را ببینیم چرا که همه چیز به سرعت اتفاق می افتد و ما زمان کافی برای کنسل کردن انیمیشن را نداریم (بعدا با روش خاصی، آن ها را نیز به شما نشان می دهم). بنابراین تمام کدهای ما به درستی کار می کنند.
توجه داشته باشید که در این انیمیشن از هیچ کد CSS ای استفاده نکرده ایم (هنوز خود انیمیشن را تعریف نکرده ایم بنابراین در مرورگر انیمیشنی را نخواهید دید) بلکه همه آن را با hook های جاوا اسکریپتی نوشته ایم و به همین دلیل است که باید done را صدا بزنیم. مسئله اینجاست که Vue نمی داند ما از هیچ کد CSS ای استفاده نکرده ایم. یادتان باشد که استفاده نکردن از name به معنی این نیست که CSS نداریم بلکه به معنی این است که از کلاس های پیش فرض (v-enter و v-enter-active و غیره) استفاده می کنیم. اگر ما به صورت دستی به Vue نگوییم که از CSS استفاده نکرده ایم، Vue به صورت پیش فرض به دنبال کلاس های CSS می گردد و زمانی که آن ها را پیدا نکند به سراغ hook های جاوا اسکریپتی ما می رود. بنابراین بهتر است به Vue بگوییم که هیج کد CSS ای را برای این انیمیشن ننوشته ایم تا سرعت برنامه بالا برود و از چک کردن های بی مورد جلوگیری کنیم.
برای این کار می توان به شکل زیر عمل کرد:
<transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @enter-cancelled="enterCancelled" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave" @leave-cancelled="leaveCancelled" :css="false" > <div style="width: 100px; height: 100px; background-color: lightgreen" v-if="load"></div> </transition>
همانطور که می بینید من از css: استفاده کرده ام. این کد به Vue می گوید به دنبال کدهای CSS نگرد تا وقت هدر نرود. همچنین حواستان باشد که علامت دو نقطه را (مخفف v-bind است) بگذارید در غیر این صورت به جای ارسال مقدار Boolean (در اینجا false)، رشته ای ساده با مقدار false را پاس خواهیم داد. بنابراین کد زیر غلط است:
css="false"
حالا نوبت به اضافه کردن کدهایی برای ساخت انیمیشن است. برای اضافه کردن انیمیشن به یک عنصر باید در enter و leave کدنویسی کنیم چرا که محل اجرای انیمیشن ها در این دو بود. اگر یادتان باشد در جلسات قبل توضیح دادم که:
با این حساب در enter می توان گفت:
methods: { beforeEnter(el) { console.log("beforeEnter"); }, enter(el, done) { console.log("enter"); let round = 1; const interval = setInterval(() => { el.style.width = el.style.width + round * 10 + "px"; }, 20); }, // بقیه کدها //
من می خواهم انیمیشن طوری باشد که مربع سبز رنگ ما کم کم بزرگ شود و سپس هنگام حذف شدن نیز کم کم کوچک تر شود. برای این کار یک متغیر به نام round تعریف کرده ایم و آن را برابر 1 گذاشته ایم. round در لغت یعنی «دفعه» یا «دور» و در اینجا منظور هر دفعه ای است که interval اجرا می شود. سپس با متد setInterval شروع می کنیم. همانطور که در کد بالا مشخص است کار interval ما این است که هر 20 میلی ثانیه، یک بار متد پاس داده شده را اجرا کند. از طرفی متد پاس داده شده باید width یا عرض عنصر را گرفته و سپس طبق فرمول بالا به عرض آن اضافه کند: در دفعه اول (round اول) 10 پیکسل به آن اضافه می کنیم، در دفعه دوم 20 پیکسل و سپس 30 پیکسل و الی آخر.
مشکل این کد این است که رشد سایز مربع ما در فرمول بالا به صورت تصاعدی خواهد بود اما من نمی خواهم اینطور باشد (بیش از حد سریع است). به نظر شما برای حل این مشکل باید چه کار کنیم؟ پاسخ این سوال را در قسمت بعد به شما خواهم داد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.