
در قسمت قبل با اضافه کردن انیمیشن به تغییر کامپوننت ها آشنا شدیم و همچنین مقدمه ای از مشکل این جلسه را بیان کردم. اگر یادتان باشد در فایل UserEdit.vue کدها را بدین شکل ویرایش کرده بودیم:
<template> <div> <h3>Edit the User</h3> <p>Locale: {{ $route.query.locale }}</p> <p>Analytics: {{ $route.query.q }}</p> <div style="height: 700px"></div> <p id="data">Some extra Data</p> </div> </template>
در همان جلسه توضیح دادم که رفتار پیش فرض مرورگرها این است که با وارد کردن # در URL می توانیم id یک عنصر خاص را هدف بگیریم تا صفحه به صورت خودکار به آن عنصر برود. در کد بالا یک Div ساده را داریم که کارش اضافه کردن 700 پیکسل به طول صفحه است تا صفحه ی ما اسکرول بخورد. سپس یک تگ p ساده را داریم که برایش id تعریف کرده ایم. حالا اگر به آدرس زیر در مرورگر برویم، مستقیما خود را در قسمت این تگ پیدا خواهید کرد:
http://localhost:8080/user/1/edit?locale=en&q=100#data
سوال من این است که چطور می توانیم این # را به همراه داده اش (data) دریافت کرده و با آن کار خاصی انجام بدهیم. ما برای پاس دادن این هش (علامت هشتگ) ابتدا به فایل UserDetail.vue می رویم و این هش را به صورت یک پارامتر دیگر پاس می دهیم:
<template> <div> <h3>Some User Details</h3> <p>User loaded has ID: {{ $route.params.id }}</p> <router-link tag="button" :to="{ name: 'userEdit', params: { id: $route.params.id }, query: { locale: 'en', q: 100 }, hash: '#data' }" class="btn btn-primary" >Edit User</router-link> </div> </template>
همانطور که می بینید پس از query یک خصوصیت دیگر به نام hash اضافه کرده ام و مقدار آن را برابر data# قرار داده ام. از آنجایی که مقدار پاس داده شده به to بسیار طولانی شده است و خواندن یا ویرایش آن سخت است، بهتر است مقدار آن را به صورت یک خصوصیت جداگانه در data تعریف کنیم و سپس آن را به to پاس بدهیم. این فایل هنوز هیچ تگ <Script> ای ندارد بنابراین خودتان آن را اضافه کنید:
<template> <div> <h3>Some User Details</h3> <p>User loaded has ID: {{ $route.params.id }}</p> <router-link tag="button" :to="link" class="btn btn-primary">Edit User</router-link> </div> </template> <script> export default { data() { return { link: { name: "userEdit", params: { id: this.$route.params.id }, query: { locale: "en", q: 100 }, hash: "#data" } }; } }; </script>
واضح است که با انجام این کار، خواندن اطلاعات to بسیار راحت تر شده است. من تغییری در کدهای قبلی نداده ام به جز اینکه برای params به جای route.params$ گفته ام this.$route.params چرا که حالا درون شیء Vue هستیم بنابراین باید از این کلید واژه استفاده نماییم. آیا با این کار مشکل ما حل شده است؟ خیر!
مشکل اینجاست که برنامه ی ما یک برنامه ی SPA است بنابراین در جا به جایی بین صفحات یا کامپوننت ها، مرورگر refresh نمی شود. به همین دلیل زمانی که با کلیک روی دکمه ی Edit User در مرورگر به صفحه ی ویرایش (آدرس http://localhost:8080/user/1/edit?locale=en&q=100#data) می رویم، به صورت خودکار به تگ <p> منتقل نشده و دیگر قابلیت اسکرول خودکار را از دست می دهیم. اسکرول شدن خودکار در مرورگر فقط زمانی اتفاق می افتد که صفحه refresh شود یا اینکه id عنصر به صورت یک لینک در صفحه وجود داشته باشد و ما روی آن کلیک کنیم. در چنین حالتی که id به صورت یک پارامتر به URL پاس داده می شود دیگر شاهد اسکرول خودکار نخواهیم بود.
اسکرول خودکار به عناصر در صفحه بر اساس id
برای اینکه به Vue بگوییم رفتار پیش فرض مرورگر مورد پسند ما است باید به فایل main.js و به قسمتی برویم که router را در آنجا تعریف کرده بودیم:
Vue.use(VueRouter); const router = new VueRouter({ routes, mode: 'history' });
اینجا باید یک خصوصیت دیگر را به Vue پاس بدهیم که ScrollBehavior نام دارد. این خصوصیت در اصل یک متد است که رفتار اسکرول مرورگر را پیکربندی می کند و سه آرگومان را دریافت می کند:
- to یعنی به کدام صفحه خواهیم رفت.
- from یعنی از کدام صفحه می آییم.
- savedPosition که موقعیت کاربر را ذخیره می کند. مثلا اگر به قسمتی از صفحه اسکرول کرده باشیم (مثلا وسط صفحه) و سپس از دکمه ی back برای برگشتن به صفحه ی قبلی استفاده کنیم، مرورگر این موقعیت را به حافظه می سپارد تا اگر خواستیم از آن استفاده کنیم.
const router = new VueRouter({ routes, mode: 'history', scrollBehavior(to, from, savedPosition) { } });
این متد از ما می خواهد که در نهایت یا یک سلکتور خاص را برگردانیم یا یک شیء را به همراه مختصات x و y برگردانیم، تا بداند به کجای صفحه اسکرول کند. مثلا برای برگرداندن مختصات x و y می گوییم:
const router = new VueRouter({ routes, mode: 'history', scrollBehavior(to, from, savedPosition) { return { x: 0, y: 700 } } });
حالا اگر به مرورگر رفته و روی دکمه ی Edit User کلیک کنید به صورت خودکار به پایین صفحه منتقل می شوید چرا که y (موقعیت عمودی – محور y ها) را روی 700 پیکسل گذاشته ایم. یادتان باشد که این رفتار به خاطر همین تابع است نه به خاطر وجود data# در URL. همچنین اگر صفحات دیگر برنامه ی ما طولانی تر بودند، در تک تک صفحات به 700 پیکسل اسکرول می شدیم. چرا؟ به دلیل اینکه هیچ فیلتری را در کد بالا تعریف نکرده ایم، بلکه گفته ایم همیشه به 700 پیکسل اسکرول کن! منتهی از آنجایی که صفحات ما طول 700 پیکسلی ندارند، چیزی را نمی بینید.
همچنین اگر بخواهید از روش پاس دادن سلکتور پیش بروید، باید به شکل زیر عمل کنید:
const router = new VueRouter({ routes, mode: 'history', scrollBehavior(to, from, savedPosition) { if (to.hash) { return { selector: to.hash }; } return { x: 0, y: 700 } } });
من در این کد گفته ام که اگر صفحه ای که می خواهیم به آن برویم (در حال منتقل شدن به آن هستیم) دارای خصوصیتی به نام hash بود، به مکان همان عنصر اسکرول کن. شیء ای که در این حالت پاس داده ام دارای خصوصیت selector است که نام دلخواه نیست و یک کلیدواژه است. من مقدار این selector را برابر To.hash گذاشته ام که یعنی همان عنصری که دارای id برابر hash است. در غیر این صورت به طور پیش فرض به 700 پیکسل اسکرول می شویم. حتی اگر 700 پیکسل را کامنت کنید باز هم در صفحه ی edit user به قسمت id=data اسکرول خواهیم شد.
در نهایت باید با savedPosition کار کنیم. فرض کنید کاربری روی editUser کلیک کرده است و به پایین صفحه رفته، سپس روی لینک دیگری کلیک کرده و به صفحات دیگری رفته است. حالا اگر کلید back را بزند و به صفحه ی قبلی (صفحه ای که # دارد) برود، خوب نیست که او را به بالای صفحه اسکرول کنیم (البته این موضوع سلیقه ای است) بلکه بهتر است که در همان موقعیت قبلی خودش باشد. بنابراین می توان گفت:
const router = new VueRouter({ routes, mode: 'history', scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition; } if (to.hash) { return { selector: to.hash }; } return { x: 0, y: 0 } } });
یعنی اگر از دکمه ی back استفاده شده بود (اگر SavedPosition داشتیم) کاربر را به همان مکان قبلی اش در صفحه برگردان و اگر در URL از # استفاده شده بود، کاربر را به موقعیت آن عنصر با آیدی # ببر و اگر هیچ کدام صحیح نبود، کاربر را با ابتدای صفحه (موقعیت های 0 و 0 برای طول و عرض) ببر.
- نصب و راهاندازی فریمورک 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