
در جلسه قبل راهی را به شما معرفی کردم که با آن می توانیم getter های خود را به صورت خودکار به خصوصیات یک کامپوننت متصل کنیم اما روش ما مشکلی جدی دارد. به کد زیر از جلسه قبل نگاه کنید (فایل AnotherResult.vue):
<template> <div> <p>Counter is: {{ doubleCounter }}</p> <p>Number of Clicks: {{ stringCounter }}</p> </div> </template> <script> import { mapGetters } from "vuex"; export default { computed: mapGetters(["doubleCounter", "stringCounter"]) }; </script>
مشکل این کد اینجاست که mapGetters تمام قسمت computed را گرفته است بنابراین نمی توانیم خصوصیات computed خود را به صورت دستی وارد کنیم. اگر بخواهیم خودمان چند خصوصیت computed داشته باشیم که مخصوص همین کامپوننت باشند و در State نباشند باید چه کار کنیم؟ احتمالا شما هم حدس زده اید که mapGetters در نهایت یک شیء جاوا اسکریپتی می سازد که به جای computed قرار می گیرد بنابراین باید راهی باشد که این شیء را با خصوصیات خودمان ترکیب کنیم. خوشبختانه قابلیتی در ES6 وجود دارد که مشکل ما را حل می کند. ما میدانیم که mapGetters در نهایت به یک شیء تبدیل می شود بنابراین می توانیم از اپراتور spread در جاوا اسکریپت استفاده کنیم تا key/value های داخل آن را جدا کنیم:
<script> import { mapGetters } from "vuex"; export default { computed: { ...mapGetters(["doubleCounter", "stringCounter"]), myComputedProp() { // کد ما اینجا قرار می گیرد } } }; </script>
در کد بالا ابتدا یک شیء را به computed داده ام و سپس mapGetters را درون آن قرار داده ام. این نحو (syntax) غلط است چرا که یک شیء نمی تواند مستقیما (به عنوان key) درون یک شیء دیگر باشد، بلکه می تواند به عنوان مقدارِ یک key قرار بگیرد. برای رفع این مشکل اپراتور spread (علامت سه نقطه پشت mapGetters) را به mapGetters داده ام. اپراتور spread (به معنی «پخش کردن») یک شیء یا آرایه را گرفته و جفت های key/value (خصوصیت و مقدار) آن را از درون آن شیء یا آرایه خارج کرده و پخش می کند. حالا می توانیم خصوصیات دیگر خود را پس از آن قرار دهیم (مثلا خصوصیت فرضی myComputedProp). شما می توانید هر تعداد خصوصیتی که خواستید درون همین شیء تعریف کنید:
<script> import { mapGetters } from "vuex"; export default { computed: { ...mapGetters(["doubleCounter", "stringCounter"]), myComputedProp() { // کد ما اینجا قرار می گیرد }, myOtherComputedProp () { // کدهای دیگر ما اینجا قرار می گیرد } } }; </script>
اگر اپراتور spread را نمی شناسید، سعی می کنم در یک مثال ساده آن را توضیح بدهم:
var obj1 = { id: 101, name: 'John Doe' } var obj2 = { age: 25, country: 'USA'}
ما در اینجا دو شیء مختلف را داریم که از هم جدا هستند. اگر بخواهیم این دو شیء را در هم ادغام کنیم، استفاده از شکل زیر مجاز نیست:
var obj1 = { id: 101, name: 'John Doe' } var obj2 = { age: 25, country: 'USA'} const employee = {obj1, obj2}
چرا؟ به دلیل اینکه در این کد، یک شیء به عنوان key در شیء دیگری قرار گرفته است و ما می دانیم که key ها نمی توانند شیء باشند (زبان جاوا اسکریپت چنین اجازه ای به ما نمی دهد). بنابراین یکی از روش های صحیح، استفاده از اپراتور spread است:
var obj1 = { id: 101, name: 'Jhon Doe' } var obj2 = { age: 25, country: 'USA'} const employee = { ...obj1, ...obj2 } console.log(employee); //{ "id": 101, "name": "John Doe", "age": 25, "country": "USA" }
این اپراتور خصوصیات id و name و age و country را از درون شیء های obj1 و obj2 خارج کرده و سپس به عنوان key/value های عادی (خارج از شیء) قرار می دهد. بنابراین اگر از کد نهایی log بگیریم، نتیجه همین کامنتی است که می بینید.
حالا به برنامه خودمان برمی گردیم. با این حساب اگر کد زیر را بنویسیم، همه چیز حل می شود؟
<script> import { mapGetters } from "vuex"; export default { computed: { ...mapGetters(["doubleCounter", "stringCounter"]) } }; </script>
پاسخ بستگی به محیط توسعه شما دارد! اگر از پکیج های به روز babel استفاده کنید، احتمالا مشکلی نخواهید داشت و کدها بدون خطا اجرا می شوند. استفاده از پکیج به روز babel کار شما نیست، بلکه کار Vue-cli است. منظور من هم این است که اگر به تازگی از Vue-cli استفاده کرده باشید مشکلی ندارید اما اگر پروژه شما قدیمی است احتمالا به مشکل بخورید (محیط babel قدیمی ممکن است نتواند این اپراتور را در Vue پیاده کند). امیدوارم یادتان باشد که برای ساخت پروژه های Vue از Vue-cli استفاده می کردیم که کدهای زیر بود:
$ npm install -g vue-cli $ vue init webpack-simple my-project $ cd my-project $ npm install $ npm run dev
بنابراین اگر کدهای شما مشکلی ندارد، تبریک می گویم. 99 درصد شما باید بدون مشکل باشید اما اگر مشکلی دارید (در کنسول مرورگر خطا دریافت می کنید) ابتدا کدهای خود را چک کنید که اشتباه نوشته نشده باشند. اگر باز هم مشکل از بین نرفت از راه حل های زیر استفاده نمایید:
- در مسیر اصلی پروژه خود پنجره ترمینال را باز کرده و دستور npm install را اجرا کنید تا پکیج های شما به روز رسانی شود (روش پیشنهادی).
- کپی کردن فایل های پروژه و ایجاد یک پروژه جدید با استفاده از Vue-Cli و قرار دادن فایل های قدیمی در آن (فقط فایل های خودتان را کپی کنید نه آن هایی که توسط npm یا به صورت خودکار ایجاد شده اند). این روش نیز روش خوبی است و تقریبا در 100 درصد مواقع جواب می دهد.
- اگر باز هم مشکل داشتید در پنجره ترمینال پکیج stage-2 یا stage-3 را برای babel نصب کنید. این روش را به عنوان آخرین راه حل در نظر بگیرید.
برای نصب stage-3 می توانید از دستور زیر استفاده کنید (نسخه پیشنهادی):
npm install –save-dev babel-preset-stage-3
برای نصب stage-2 می توانید از دستور زیر استفاده کنید (برای پروژه های قدیمی که به دلایلی نمی توانند به روز رسانی شوند یا روش های دیگر برایتان کار نکرده است):
npm install –save-dev babel-preset-stage-2
فایل package.json من در زمان نوشتن این مقاله به شکل زیر است (در آینده برای شما متفاوت خواهد بود چرا که دائما به روز رسانی می شود):
"devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.0", "babel-preset-stage-3": "^6.24.1", "cross-env": "^5.0.5", "css-loader": "^0.28.7", "file-loader": "^1.1.4", "vue-loader": "^13.0.5", "vue-template-compiler": "^2.4.4", "webpack": "^3.6.0", "webpack-dev-server": "^2.9.1" }
اگر از روش سوم (نصب stage-2) استفاده کردید، باید پس از نصب به فایل babelrc. بروید و stage-2 را به آن اضافه کنید:
{ "presets": [ ["env", { "modules": false }], ["stage-2"] ] }
اگر از نسخه های به روز استفاده کرده باشید، babelrc. حاوی کدهای زیر است (صرفا جهت اطلاع، آن را دست کاری نکنید):
{ "presets": [ ["env", { "modules": false }], "stage-3" ] }
حالا که مشکل خصوصیات computed را حل کرده ایم در جلسه بعد در مورد mutation صحبت خواهیم کرد.
- نصب و راهاندازی فریمورک 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