
در جلسات قبل به طور کامل با انواع اعتبارسنجی های مهم آشنا شدیم. البته لازم به ذکر است که زمان کافی برای بررسی تک تک موارد را نداشتیم و شما می توانید اطلاعات بیشتری را در صفحه رسمی Vuelidate پیدا کنید، گرچه که مباحث زیادی باقی نمانده است. یکی از کار هایی که دوست دارم با برنامه مان انجام بدهیم، غیرفعال کردن دکمه submit در صورت داشتن خطا در فرم است. برای این کار روش های مختلفی وجود دارد. به طور مثال می توانیم Disabled را با v-bind به دکمه submit متصل کنیم اما چطور باید این کار را انجام بدهیم؟ آیا باید هر فیلد را جداگانه به disabled پاس بدهیم. مثلا:
<button type="submit" :disabled="$v.email.$error || $v.age.$error || ...">Submit</button>
قطعا این کار بسیار سختی است و فقط برای فرم های بسیار کوچک جواب می دهد. اگر یادتان باشد ما به خصوصیت error$ روی شیء اصلی v$ (شیء vuelidate) نیز دسترسی داریم بنابراین می توان گفت:
<button type="submit" :disabled="$v.$error">Submit</button>
اما این روش نیز جالب نیست چرا که دکمه submit باید از همان ابتدا غیر فعال باشد نه اینکه منتظر تایپ کردن کاربر بمانیم و سپس دکمه را غیر فعال کنیم. چنین کاری منطقی نیست. بنابراین به جای error می توانیم از invalid استفاده کنیم:
<button type="submit" :disabled="$v.$invalid">Submit</button>
با این کار دکمه submit از همان ابتدای کار غیر فعال می باشد. بنابراین کاربر باید تمام موارد فرم را درست پر کند تا این دکمه فعال شود.
اعتبارسنجی ناهمگام (async validation)
اعتبارسنجی های ناهمگام یا نامتقارن (asynchronous) به اعتبارسنجی هایی می گویند که به سرور وابسته است بنابراین تمام کار هایی که تا این قسمت انجام داده ایم، اعتبارسنجی همگام (synchronous) بوده است. اگر یادتان باشد برایتان توضیح داده بودم که firebase ایمیل های تکراری را برای ثبت نام قبول نمی کند بنابراین این یک فرصت عالی برای بررسی ایمیل از سمت firebase و نمایش فیدبک در UI است. برای انجام این کار باید validator های شخصی خود را بسازیم چرا که validator ای از پیش برای این کار تعریف نشده است. برای این کار به rule set مربوط به email رفته و نامی برای validator خود انتخاب می کنم. من unique (به معنی «یکتا» یا «منحصر به فرد») را انتخاب می کنم که نشان دهنده تکراری نبودن ایمیل است اما شما می توانید هر چیز دیگری را انتخاب کنید. validator ها در ساده ترین حالت یک تابع هستند بنابراین می توان گفت:
email: { required, email, unique: val => { } }
val (یا هر نام دیگر که شما برایش بگذارید) همان مقدار موجود در input مربوطه (در اینجا، ایمیل تایپ شده) است که به صورت خودکار توسط vuelidate پاس داده می شود. شما باید درون این تابع true یا false را برگردانید. مثلا اگر بخواهیم به صورت محلی و بدون اتصال به firebase کار کنیم، به راحتی می گوییم:
email: { required, email, unique: val => { return val !== "roxo3@info.ir"; } },
یعنی ایمیل من نباید roxo3@info.ir باشد. در واقع اگر val (ایمیل تایپ شده) برابر نباشد، شرط صحیح بوده و true برگردنده می شود و در غیر این صورت شرط غلط بوده و false برگردانده می شود. حالا اگر به مرورگر بروید و هر ایمیلی به جز roxo3@info.ir را وارد کنید، تایید می شود اما roxo3@info.ir خطا می دهد. حالا بیایید کمی این کد را بهتر کنیم:
email: { required, email, unique: val => { if (val === "") return true; return new Promise((resolve, reject) => { resolve(val !== "roxo3@info.ir"); }); } },
در ابتدا یک شرط if نوشته و گفته ام اگر Val یک رشته خالی بود true را برگردان. چرا؟ این کار دو دلیل اصلی دارد:
- اولا اگر یک رشته خالی داشتیم، یعنی کاربر چیزی را تایپ نکرده است یا اگر قبلا چیزی وجود داشته است، توسط کاربر پاک شده است. بنابراین چرا باید یک رشته خالی را برای اعتبارسنجی به سمت سرور ارسال کنیم؟ مشخص است که رشته های خالی نباید اعتبارسنجی شوند.
- دوما چرا false را return نکنیم؟ به دلیل اینکه کار unique بررسی تکراری بودن یک ایمیل است نه وجود ایمیل! وجود ایمیل و معتبر بودن ساختار آن توسط دو validator دیگر ما به نام های required و email بررسی می شوند. اگر ما در unique مقدار false را برگردانیم، انگار گفته ایم که این ایمیل تکراری است! و یک رشته خالی نمی تواند در پایگاه داده ما ثبت شود چه برسد که تکراری باشد. سعی کنید validator های خود را با هم قاطی نکنید!
در ادامه کد یک Promise را ساخته ام. ساختار vuelidate بدین صورت است که اگر بخواهید validator های خود را به صورت async داشته باشید باید یک Promise برگردانید (گرچه که کد بالا هنوز async نیست). من انتظار دارم که شما با Promise ها آشنا باشید چرا که از مباحث جاوا اسکریپت هستند و ربطی به Vue ندارند. اگر با آن ها آشنایی ندارید کلمه Promise را در روکسو پلاس جست و جو کرده و مقالات مختلف ما را مطالعه کنید. هر promise یک resolve و یک reject می گیرد که به ترتیب برای قبول کردن و رد کردن درخواست استفاده می شوند. بنابراین کد بالا می گوید اگر val برابر roxo3@info.ir نبود،
برای اینکه بتوانیم واقعا به firebase چیزی را ارسال کنیم باید index را در Firebase تعریف کنیم. برای این کار به پایگاه داده Firebase خودتان رفته و سربرگ rules را به شکل زیر تغییر دهید:
{ "rules": { ".read": "true", ".write": "auth != null", "users": { ".indexOn": ["email"] } } }
خصوصیت indexOn به firebase می گوید به ما اجازه بدهد تا بر اساس email کاربران را جست و جو کنیم. همچنین read را روی true گذاشته ام تا مجبور به گرفتن توکن و login شدن نباشیم. حالا به جای اینکه Promise را خودمان ساخته و برگردانیم، می توانیم از Promise برگردانده شده از سمت Firebase استفاده کنیم. برای این کار ابتدا axios را import می کنیم:
<script> import { required, email, numeric, minValue, minLength, sameAs, requiredUnless } from "vuelidate/lib/validators"; import axios from "axios";
سپس باید به firebase کوئری بزنیم که آیا ایمیل وارد شده توسط کاربر قبلا در پایگاه داده ثبت شده است یا خیر؟ اگر ایمیل ثبت شده باشد، پاسخ برگردانده شده از Firebase دارای قسمتی به نام Data است که آن کاربر را به شکل یک شیء جاوا اسکریپتی برمی گرداند اما اگر وجود نداشته باشد، قسمت data خالی خواهد بود. بنابراین:
email: { required, email, unique: val => { if (val === "") return true; return axios .get('/users.json?orderBy="email"&equalTo="' + val + '"') .then(res => { return Object.keys(res.data).length === 0; }); } },
در اینجا با متد Get از Axios به آدرس user.json یک کوئری ارسال کرده ام (اگر از فصل قبل یادتان بیاید، ابتدای آدرس در فایل main.js ذخیره شده است). کوئری ما می گوید orderBy (یعنی «مرتب کن بر اساس») و سپس email را به آن پاس داده ایم که همان فیلد email در پایگاه داده برای کاربران است. سپس گفته ایم equalTo (یعنی «برابر است با») و Val (ایمیل تایپ شده توسط کاربر) را به آن داده ایم. هم email و هم val باید درون double quotation قرار بگیرند و این موضوع از قوانین firebase است. سپس یک promise به ما برگردانده می شود که با Then آن را گرفته و بررسی می کنیم. متدی به نام keys در شیء Object در جاوا اسکریپت وجود دارد (ربطی به Vue ندارد) که key های یک شیء را به ما می دهد. از طرفی گفتم که اگر ایمیل تکراری نباشد، قسمت data در پاسخ firebase حتما خالی است بنابراین می گوییم اگر promise برگردانده شده از سمت Firebase هیچ کلیدی نداشته باشد (length یا تعداد کلیدها برابر 0 بود) باید true برگردانده شود. در واقع کل این شرط به true یا false تغییر می کند و return خواهد شد. به راحتی می توانید این کد را در مرورگر خود تست کنید (یادتان باشد که firebase در ایران تحریم است و ابزار ضد تحریم شما باید روشن باشد).
- نصب و راهاندازی فریمورک 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