
در قسمت قبل لیستی ایجاد کردیم که دارای دکمه ای برای اضافه کردن عناصر جدید به آن بود و همچنین با کلیک روی هر کدام از اعضای این لیست، می توانستیم آن را از بین ببریم. مسئله اینجاست که عملیات حذف و اضافه کردن آیتم ها فعلا هیچ انیمیشنی ندارد و ما می خواهیم انیمیشن های دلخواه خود را به آن اضافه کنیم. یادتان باشد که نمی توانیم مثل همیشه از <transition> استفاده کنیم چرا که در <transition> همیشه باید یک عنصر نمایش داده شود اما اینجا لیستی از عناصر را داریم (چندین و چند <li>). بنابراین راه حل ما استفاده از <transition-group> است اما آیا استفاده از آن مانند <transition> می باشد؟ خوشبختانه پاسخ این سوال مثبت است؛ چه از کلاس های CSS و چه از hook های جاوا اسکریپتی برای اضافه کردن انیمیشن استفاده کنید، روند دقیقا یکی است.
تنها تفاوتی که بین <transition> و <transition-group> وجود دارد، این است که <transition> چیزی را به DOM اضافه نمی کند اما <transition-group> یک تگ <span> را به DOM اضافه خواهد کرد. ما نمی توانیم جلوی این مسئله را بگیریم اما می توانیم نوع تگ را به شکل زیر عوض کنیم:
<transition-group tag="YourTag">
به جای YourTag باید تگ مورد نظر خود را بنویسید. مثلا اگر بخواهیم به جای <span> یک تگ <p> اضافه شود می گوییم:
<transition-group tag="p">
برای شروع این جسله به فایل App.vue رفته و از <transition-group> استفاده می کنیم:
<ul class="list-group"> <transition-group name="slide"> <li class="list-group-item" v-for="(number, index) in numbers" @click="removeItem(index)" style="cursor: pointer" >{{ number }}</li> </transition-group> </ul>
توجه کنید که خود <ul> درون <transition-group> قرار ندارد. من می خواهم از انیمیشن slide استفاده کنم (قبلا آن را تعریف کرده ایم) بنابراین مثل همیشه name را با مقدار slide به آن می دهم. حالا سوال این است که آیا کد بالا بدون مشکل کار می کند؟ پاسخ منفی است! اگر کدها را ذخیره کرده و در مرورگر باز کنید، کل لیست از بین می رود و دیگر نمایش داده نمی شود.
مشکل همان مشکلی است که قبلا با آن روبرو شده بودیم. اگر یادتان باشد در جلسات قبل هنگامی که با کادر های info و warning کار می کردیم، هر دو div را درون یک <transition> قرار دادیم تا یکی را مخفی کرده و دیگری را نمایش بدهیم:
<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>
اینجا هم همین مشکل را داشتیم و هر دو div کاملا مخفی می شدند. من در آن قسمت توضیح دادم که Vue توانایی تشخیص تفاوت بین این دو div را ندارد و اگر دو یا چند عنصر یکسان (مثلا چند div یا چند <li> یا هر عنصر دیگری) را به <transition> بدهیم، باید برایشان key تعریف کنیم تا Vue بفهمد که این عناصر، عناصر جداگانه ای هستند. البته این توضیحات مربوط به <transition> بود و در <transition-group> باید همیشه برای تمام عناصر key تعریف کنیم حتی اگر یکسان نباشند. بنابراین می گوییم:
<ul class="list-group"> <transition-group name="slide"> <li class="list-group-item" v-for="(number, index) in numbers" @click="removeItem(index)" style="cursor: pointer" :key="number" >{{ number }}</li> </transition-group> </ul>
اگر یادتان باشد در جلسه قبل کدها را طوری نوشتیم که هیچ عدد تکراری درون آرایه numbers نداشته باشیم (همیشه یک واحد به طول آرایه اضافه می کردیم و آن را به عنوان عنصر جدید تحویل لیست می دادیم) بنابراین خود number بهترین مقدار برای key است چرا که یکتا است و هیچ وقت تکرار نمی شود. همچنین یادتان باشد که علامت دو نقطه (مخفف v-bind) را بگذارید تا رشته ساده number را به آن پاس ندهید بلکه مقدار پویای number (به عنوان یک متغیر نه یک رشته) را به آن بدهیم. اگر کدهای بالا را ذخیره کرده و به مرورگر بروید، تمام کدها بدون مشکل کار می کنند و حالا یک انیمیشن جالب داریم. تنها مشکل اینجاست که در این انیمیشن شاهد یک جهش در هنگام اضافه کردن یا حذف آیتم های لیست هستیم. یعنی زمانی که روی دکمه کلیک می کنیم تا عنصری به لیست اضافه شود، ابتدا عناصر جهش می کنند تا برای عنصر ما جا باز کنند و سپس آن عنصر به آرامی وارد لیست می شود.
خوشبختانه <transition-group> یک کلاس اضافی نسبت به <transition> دارد که مسئول همین کار است. ما می توانیم به قسمت style در همان فایل app.vue رفته و به دنبال کلاس های slide بگردیم:
.slide-enter { opacity: 0; /*transform: translateY(20px);*/ } .slide-enter-active { animation: slide-in 1s ease-out forwards; transition: opacity 0.5s; } .slide-leave { } .slide-leave-active { animation: slide-out 1s ease-out forwards; transition: opacity 1s; opacity: 0; }
حتما به خاطر دارید که تمام این کلاس ها را در جلسات اول این فصل تعریف کرده بودیم. کلاس اضافی ما slide-move است و می توانیم آن را به شکل زیر اضافه کنیم:
.slide-leave-active { animation: slide-out 1s ease-out forwards; transition: opacity 1s; opacity: 0; } .slide-move { transition: transform 1s; }
خصوصیت transform در اینجا ربطی به transform استفاده شده در keyframe ها ندارد، بلکه Vue همیشه از این خصوصیت برای جا به جا کردن عناصر استفاده می کند (چه translateX و چه translate بر اساس نیاز استفاده خواهد شد). از آنجایی که Vue از transform برای حرکت دادن عناصر استفاده می کند، ما می توانیم به آن transition استفاده کنیم تا عملیات به نرمی و با انیمیشن صورت بگیرد. بنابراین در این کد به CSS گفته ایم که اگر خصوصیت transform تغییر کرد به آن انیمیشن اضافه کن (زمانی که Vue عنصری را جا به جا کند مقادیر translateX یا translate تغییر خواهند کرد بنابراین قابل تشخیص خواهند بود). در ضمن اگر قرار به استفاده از انیمیشن دیگری بود باید عینا همین مراحل را بروید. مثلا اگر بخواهیم به جای slide از fade (یا هر نامی که خودتان انتخاب کرده اید) استفاده کنیم، مراحل تغییری نخواهند کرد.
حالا اگر کدها را ذخیره کرده و به مرورگر برویم، در هنگام کلیک روی دکمه Add Item یک آیتم جدید با انیمیشن کاملا مطلوب اضافه خواهد شد بنابراین کد ما کار می کند اما اگر روی یکی از این آیتم ها کلیک کنیم تا حذف شود، باز هم شاهد آن جهش خواهیم بود! چرا؟ به دلیل اینکه آیتم در حال حذف در زیر یا بالای خود آیتم های دیگری دارد. این آیتم ها جزئی از document flow هستند (همان ساختار HTML صفحه و نحوه روی هم نشستن عناصر) و این Flow تغییر نمی کند مگر آنکه عنصری حذف شود و جای خالی برای بقیه عناصر به وجود بیاورد. مثلا امکان ندارد که آیتم های یک لیست به صورت خودکار جا به جا شوند یا تصویری در صفحه HTML به قسمت پایین تری برود مگر آنکه جای خالی پیدا شود. با این حساب اضافه کردن انیمیشن به آن ها هیچ فایده ای ندارد چرا TranslateY (حرکت عمودی) در حالت عادی اجازه نمی دهد عناصر روی هم بروند مگر اینکه position روی absolute باشد. بنابراین به کلاس slide-leave-active می رویم (این کلاس به عنصر در حال حذف اضافه می شود) و می گوییم:
.slide-leave-active { animation: slide-out 1s ease-out forwards; transition: opacity 1s; opacity: 0; position: absolute; }
همانطور که می دانید، position: absolute به عناصر HTML اجازه می دهد که روی هم بروند. حالا اگر کدها را ذخیره کرده و به مرورگر بروید، همه چیز به درستی دارای انیمیشن است. دانلود سورس کد این قسمت.
- نصب و راهاندازی فریمورک VueJS
- مثالی قویتر و نصب محلی Vue
- درکی ساده از Tamplateها در Vue
- درک بهتر Directiveها + برخی از Directiveهای مشهور
- تعامل با Event Listenerها
- قدرت Vue با انواع Modifierها
- مبحث two-way-binding و پاسخ به تغییرات
- خصوصیات محاسبهشده (Computed Properties)
- روش جایگزین خصوصیات Computed
- استایلدهی پویا با اشیاء
- استایلدهی پویا اسمی بدون استفاده از کلاسها
- ایجاد شرط با v-if
- نمایش لیستها با v-for
- گردش درون اشیاء
- رهگیری عناصر در v-for
- اولین پروژه تمرینی – آمادهسازی اولیه
- پیادهسازی منطق شروع بازی
- تکمیل دکمه Attack
- کدنویسی متدهای باقیمانده در بازی
- نمایش log و اتمام پروژه
- آشنایی و تعامل بیشتر با شیء Vue
- نحوه مدیریت دادهها در شیء Vue
- استفاده از ref$ در قالبهای HTML
- آشنایی با Mount کردن Templateها
- نحوه بهروزرسانی DOM و چرخه زندگی شیء Vue
- استفاده از Lifecycleها در عمل
- راهاندازی سرور محلی Vue
- آشنایی با Vue CLI
- درک بهتر فایلهای Vue
- آشنایی با کامپوننتها
- ساخت کامپوننتها
- استفاده از کامپوننتها و قوانین آن
- ارتباط بین کامپوننتها با Props
- اعتبارسنجی Props
- رویدادهای شخصیسازیشده
- ارتباط بین کامپوننتهای خواهر و برادر
- استفاده از یک شیء سراسری Vue
- آشنایی با Slotها
- بررسی جزئیات بیشتری از Slotها
- قابلیتی جدید به نام Dynamic Components
- مرگ کامپوننتهای پویا
- فصل جدید و پروژه جدید
- پروژه Quote – پاسدادن دادهها با Prop
- پروژه Quote – تکمیل ثبت Quote
- تکمیل پروژه Quoteها
- فصل جدید، کار با فرمها
- کار با عناصر Textarea
- عناصر Checkbox و Radiobutton
- کار با منوهای آبشاری و جزئیات v-model
- تعریف عناصر شخصیسازیشده
- نگاهی عمیقتر به Directiveها
- ساخت یک Directive شخصی
- ثبت محلی Directiveها + قدمی پیشرفتهتر
- آشنایی با Filterها
- جایگزینی برای Filterها
- آشنایی با Mixinها
- جزئیات تکمیلی در مورد Mixinها
- آشنایی با انیمیشنها در Vue
- استفاده عملی از Transition و Animation
- ترکیب Transition و Animation
- استفاده از کلاسهای CSS مختلف
- تبدیل عناصر مختلف به یکدیگر با انیمیشن
- اعمال انیمیشن با جاوا اسکریپت
- کدنویسی متدهای مربوط به hookهای جاوا اسکریپتی
- تکمیل انیمیشن جاوا اسکریپتی + کامپوننتهای پویا
- ساخت یک لیست برای انیمیشنهای گروهی
- اضافهکردن انیمیشن به لیست ساختهشده
- مینی پروژه فصل – سوالات ریاضی
- تکمیل پروژه و اضافهکردن انیمیشن
- فصل جدید، درخواستهای HTTP
- ارسال اطلاعات به Firebase
- دریافت دادهها از Firebase
- آشنایی با Interceptorها در Vue-Resource
- آشنایی با مفهوم Resource در Vue-Resource
- جزئیات تکمیلی Resourceها
- فصل جدید، آشنایی با Routing
- آشنایی با Routing Modes و اضافهکردن لینکها
- استایلدهی لینک فعال
- ایجاد Navigation با کد و پارامترهای URL
- واکنش به تغییرات URL و پارامترهای آن
- ساخت URLهای پویاتر با Named Routes
- مباحث Query Parameter و Redirection
- مبحث Redirect و اضافهکردن انیمیشن
- پاسدادن # و کنترل عملیات اسکرول
- محافظت از Routeها با استفاده از Gaurdها (قسمت اول)
- محافظت از Routeها با استفاده از Gaurdها (قسمت دوم)
- بارگذاری Routeها به صورت lazy
- فصل جدید، آشنایی با VueX
- نحوهی پیادهسازی اولیهی پکیج VueX
- آشنایی با Getterها در VueX
- اتصال خودکار Getterها به خصوصیات
- حل مشکل ترکیب Getterها و Computed Props
- آشنایی با مبحث Mutation در VueX
- آشنایی با Actionها در Mutations
- درک عملیاتهای پشت صحنه در mapActions
- خلاصهی جلسات قبل + معرفی مشکلی جدید
- اعمال two-way-binding در VueX
- ماژولار کردن مدیریت State در VueX
- استفاده از Namespaceها در VueX
- فصل جدید، پروژهی نهایی دوره
- پیادهسازی Header یا Navigation سایت
- ایجاد ساختار برای قسمت سهام (stocks)
- اضافهکردن منطق دکمهی Buy
- پیادهسازی VueX روی پروژه
- تعریف Mutationهای ماژول Portfolio در VueX
- پیادهسازی Getters برای ماژول Portfolio در VueX
- تکمیل کامپوننت Portfolio و نمایش سهام
- اعتبارسنجی برای فروش سهام و استفاده از فیلترها
- نمایش Funds و اعتبارسنجی برای خرید سهام
- پایان دادن به روز + اضافه کردن انیمیشن به صفحات
- پیادهسازی drop-down و راهاندازی Firebase
- ذخیره و دریافت قیمتها با درخواستهای PUT و GET
- تکمیل دکمهی Load Data و کار با Vue dev Tools
- خروجیگرفتن نهایی از برنامه برای قرارگیری روی سرور
- فصل پیوست ۱: استفاده از axios به جای vue-resource
- فصل پیوست ۱: درخواست GET در axios
- فصل پیوست ۱: استفاده از Interceptorها در Axios
- فصل پیوست ۲: احراز هویت در برنامههای SPA
- فصل پیوست ۲: ساخت کاربر جدید با ایمیل و رمز عبور
- فصل پیوست ۲: دریافت توکن احراز هویت در مرورگر
- فصل پیوست ۲: تکمیل منطق برنامه و کدهای باقیمانده
- فصل پیوست ۲: پیوست توکن به درخواستهای خروجی
- فصل پیوست ۲: بهینهسازی برنامه و Path Guard
- فصل پیوست ۲: اضافهکردن مکانیسم logout از حساب
- فصل پیوست ۲: پیادهسازی logout خودکار از حساب
- فصل پیوست ۲: ذخیرهی دادهها در localStorage
- فصل پیوست ۲: پیادهسازی فرآیند login خودکار
- فصل پیوست ۳: فصل جدید، اعتبارسنجی دادههای کاربر
- فصل پیوست ۳: ارائهی فیدبک اعتبارسنجی در UI
- فصل پیوست ۳: آشنایی با Validatorهای عددی
- فصل پیوست ۳: آشنایی با Validatorهای رمز عبور
- فصل پیوست ۳: آشنایی با requiredUnless
- فصل پیوست ۳: اعتبارسنجی آرایههای پویا
- فصل پیوست ۳: ثبت فرم و اعتبارسنجیهای ناهمگام
- فصل پیوست ۴: نسخهی 3 از Vue CLI
- فصل پیوست ۴: آشنایی با پروژه در CLI جدید
- فصل پیوست ۴: استفاده و کار با پلاگینها در CLI جدید
- فصل پیوست ۴: آشنایی با Environment Variables
- فصل پیوست ۴: خروجی گرفتن از برنامه نهایی
- فصل پیوست ۴: شخصیسازی بیشتر Build
- فصل پیوست ۴: استفاده از GUI