
در قسمت قبل با validator ای به نام requiredUnless آشنا شدیم و با استفاده از آن منوی آبشاری Country را اعتبارسنجی کردیم و حالا نوبت به آرایه ها می رسد. آرایه فعلی ما بدین شکل است:
<div class="hobbies"> <h3>Add some Hobbies</h3> <button @click="onAddHobby" type="button">Add Hobby</button> <div class="hobby-list"> <div class="input" v-for="(hobbyInput, index) in hobbyInputs" :key="hobbyInput.id"> <label :for="hobbyInput.id">Hobby #{{ index }}</label> <input type="text" :id="hobbyInput.id" v-model="hobbyInput.value" /> <button @click="onDeleteHobby(hobbyInput.id)" type="button">X</button> </div> </div> </div>
یعنی هر بار که کاربر روی گزینه Add Hobby کلیک می کند، یک فیلد جدید برایش ساخته می شود که می تواند hobby (سرگرمی) های خودش را درون آن وارد کند. در قدم اول نیاز به یک rule set داریم بنابراین به خصوصیت validations در شیء Vue خود رفته و آن را اضافه می کنیم:
hobbyInputs: { minLen: minLength(1), $each: { value: { } } }
در ابتدا از minLength استفاده کرده ام و گفته ام تعداد اعضای آرایه ما باید حداقل یک عضو باشد. سپس از خصوصیت ویژه ای به نام each$ استفاده کرده ام که مشخص کننده تک تک اعضای آرایه است. ما در هنگام برنامه نویسی نمی دانیم که کاربر چند عضو به آرایه خواهد داد بنابراین می توانیم از each$ به جای تمام آن ها استفاده کنیم. حالا درون each$ می توانیم به داده های درون hobbyInputs دسترسی داشته باشیم. اگر به کد اول در این مقاله نگاه کنید متوجه می شوید که من hobbyInput.value را با استفاده از v-model به input خودم متصل کرده ام. همچنین می توانیم به متد onAddHobby نگاه کنیم:
onAddHobby() { const newHobby = { id: Math.random() * Math.random() * 1000, value: "" }; this.hobbyInputs.push(newHobby); },
در اینجا نیز مشخص است که هر عضو آرایه ما یک id و یک value دارد و این value در ابتدا روی یک رشته خالی تنظیم شده است. با این حساب باید درون each$ از value استفاده کنیم تا به آن دسترسی داشته باشیم:
hobbyInputs: { minLen: minLength(1), $each: { value: { required, minLen: minLength(5) } } }
با این حساب value ها اجباری هستند و باید حداقل 5 کاراکتر داشته باشند (منظور مقدار هر value است). کار ما با این قسمت تمام شده است و حالا باید این rule set را به Add hobby متصل کنیم:
<div class="hobbies"> <h3>Add some Hobbies</h3> <button @click="onAddHobby" type="button">Add Hobby</button> <div class="hobby-list"> <div class="input" v-for="(hobbyInput, index) in hobbyInputs" :class="{invalid: $v.hobbyInputs.$each[index].$error}" :key="hobbyInput.id" > <label :for="hobbyInput.id">Hobby #{{ index }}</label> <input type="text" :id="hobbyInput.id" @blur="$v.hobbyInputs.$each[index].value.$touch()" v-model="hobbyInput.value" /> <button @click="onDeleteHobby(hobbyInput.id)" type="button">X</button> </div> <p v-if="!$v.hobbyInputs.minLen" >You have to specify at least {{ $v.hobbyInputs.$params.minLen.min }} hobbies.</p> </div> </div>
توضیحات کد بالا:
در قدم اول به div با کلاس input می رویم که دربرگیرنده hobby های ما است و مثل همیشه class را با v-bind به آن اضافه می کنیم. تنها تفاوت این کد با کد های قبلی، وجود each$ است که باید index آن عضو از آرایه hobbyInputs را بگیرد. من index را در همان حلقه v-for استخراج می کنم بنابراین به راحتی به آن دسترسی داریم. نکته اینجاست که من می توانستم کد را به شکل زیر نیز بنویسم:
:class="{invalid: $v.hobbyInputs.$each[index].value.$error}"
اما شاید بخواهیم خطا را در سطح کلی تری بررسی کنیم نه فقط در سطح value، به همین خاطر از نوشتن value صرف نظر کرده ام. در مرحله بعد به سراغ خود input رفته و رویداد blur را روی آن صدا زده ام. سپس مثل دفعات قبل عمل کرده ام اما این بار each$ را داریم و باید index را به آن پاس بدهیم. در نظر داشته باشید که دلیل استفاده از each، پویا بودن این آرایه و فرم است. فرم ما طوری طراحی شده است که input ها به صورت پویا و به ازای کلیک کاربر ساخته می شوند و ما نمی دانیم چند input خواهیم داشت. اینجاست که each$ به کمک ما می آید. در نهایت یک تگ <p> را به فرم اضافه کرده ام که بر اساس minLen آرایه hobbyInputs نمایش داده می شود (با یک v-if) و به کاربر می گوید که باید حداقل X تعداد hobby داشته باشد، به طوری که X برابر با همان minLength است که ما آن را روی 1 عضو گذاشته بودیم.
البته اگر به مرورگر برویم این خطا را مشاهده نمی کنیم. چرا؟ در حالت عادی هیچ فیلد input ای نداریم مگر آنکه کاربر روی دکمه Add Hobby کلیک کند. از طرفی کد های اعتبارسنجی ما درون این قسمت از فرم وجود دارد که به صورت پویا ساخته می شود بنابراین در حالت اولیه، اصلا اعتبارسنجی وجود ندارد. اعتبارسنجی فقط زمانی اجرا می شود که کاربر روی Add Hobby کلیک کند. از طرفی اگر روی Add Hobby کلیک کند نیز یک فیلد input ساخته است که شرط ما را برقرار می کند (حداقل یک عضو) بنابراین هیچ وقت خطایی نمی بینیم. برای حل این مشکل من minLen را روی 2 می گذارم:
hobbyInputs: { minLen: minLength(2), $each: { value: { required, minLen: minLength(5) } } }
حالا اگر به مرورگر برویم و Add Hobby را بزنیم حتما خطا را می بینیم:

همچنین اعتبارسنجی روی تک تک input ها (حداقل مقدارشان باید پنج کاراکتر باشد) نیز اعمال می شود اما یادتان باشد که اعتبارسنجی را روی Blur تنظیم کرده بودیم بنابراین فقط زمانی اعتبارسنجی انجام می شود که ابتدا روی فیلد کلیک کرده و سپس از آن خارج شویم. شما می توانید این کد ها را در مرورگر خود تست نمایید. البته برای اینکه مطمئن شویم کاربر بدون کلیک روی Add Hobby فرم را ثبت نمی کند، می توانیم به hobbyInputs در Validations رفته و required را به آن اضافه کنیم:
hobbyInputs: { required, minLen: minLength(2), $each: { value: { required, minLen: minLength(5) } } }
با این کار منطق اعتبارسنجی کامل می شود اما خطایی به کاربر نمایش نمی دهیم مگر آنکه روی Add Hobby کلیک کند. برای حل این مشکل می توان شرط نمایش را کمی تغییر داد:
<p v-if="!$v.hobbyInputs.minLen || !$v.hobbyInputs.required" >You have to specify at least {{ $v.hobbyInputs.$params.minLen.min }} hobbies.</p>
یا اینکه یک <p> دیگر ایجاد کرد:
<p v-if="!$v.hobbyInputs.minLen" >You have to specify at least {{ $v.hobbyInputs.$params.minLen.min }} hobbies.</p> <p v-if="!$v.hobbyInputs.required">Please add hobbies.</p>
در هر دو حالت برنامه ما به خوبی کار می کند.
- نصب و راهاندازی فریمورک 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