حل مشکل ترکیب Getterها و Computed Props

Solving the Problem of Combining Getters and Computed Props

Vue.JS 2: حل مشکل ترکیب getter ها و computed props - قسمت 92

در جلسه قبل راهی را به شما معرفی کردم که با آن می توانیم 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

هشدار: اگر از نسخه های به روز استفاده کنید (در شش ماه اخیر با vue-cli پروژه خود را ایجاد کرده باشید)، stage-3 به صورت خودکار برایتان نصب شده است (vue-cli این کار را می کند) بنابراین نیازی به نصب هیچ چیز اضافه ای نیست. فقط زمانی دست به نصب این پکیج ها بزنید که واقعا کدهای شما در مرورگر اجرا نمی شوند. برای اطمینان می توانید فایل package.json را بررسی کنید. همچنین تا جای ممکن از نصب نسخه های قدیمی پرهیز کنید.

فایل 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 صحبت خواهیم کرد.

cpluskey.com

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان Vue js از صفر تا صد توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.