اتصال خودکار Getterها به خصوصیات

Automatically Connect Getters to Properties

Vue.JS 2: اتصال خودکار getter ها به خصوصیات - قسمت 91

در جلسه قبل برایتان توضیح دادم که چرا داشتن یک فایل برای ذخیره سازی خصوصیات کافی نیست و باید getter ها را نیز به آن ها اضافه کنیم اما در این جلسه می خواهم قابلیت جالبی از getter ها را به شما نشان بدهم. فرض کنید که می خواهیم یک getter دیگر به نام stringCounter نیز تعریف کنیم. برای این کار باید به فایل store.js رفته و مانند جلسه قبل عمل نماییم:

export const store = new Vuex.Store({
    state: {
        counter: 0
    },
    getters: {
        doubleCounter: state => {
            return state.counter * 2;
        },
        stringCounter: state => {
            return state.counter + ' Clicks';
        }
    }
});

این getter شماره counter را گرفته و به clicks اضافه می کند تا چیزی شبیه به جمله زیر ایجاد شود:

3 clicks

حالا به AnotherResult.vue می رویم تا از آن استفاده کنیم:

<template>
  <div>
    <p>Counter is: {{ counter }}</p>
    <p>Number of Clicks: {{ clicks }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    counter() {
      return this.$store.getters.doubleCounter;
    },
    clicks() {
      return this.$store.getters.stringCounter;
    }
  }
};
</script>

من در ابتدا خصوصیتی به نام clicks را درون خصوصیات computed تعریف کرده و با استفاده از getter خودمان (stringCounter) مقدارش را تعیین کرده ایم. سپس همین خصوصیت را درون یک تگ <p> در قسمت template نمایش داده ام. به عنوان یادآوری از فصل اول، حواستان باشد که نوشتن کدها به شکل زیر غلط است:

<template>
  <p>Counter is: {{ counter }}</p>
  <p>Number of Clicks: {{ clicks }}</p>
</template>

در فصل های اول به شما توضیح دادم که درون template فقط یک عنصر ریشه ای قبول خواهد شد، به عبارت دیگر template فقط باید یک فرزند مستقیم داشته باشد. به همین دلیل است که از تگ های <p> خود را درون div قرار داده ام. اگر کد بالا را ذخیره کرده و به مرورگر بروید، هیچ مشکلی نخواهیم داشت:

اجرای بدون مشکل number of clicks
اجرای بدون مشکل number of clicks

هر کلیک روی دکمه increment دو واحد به شمارنده اضافه می کند بنابراین برای اضافه شدن 4 واحد، دو کلیک خواهیم داشت. با اینکه این کد مشکل خاصی ندارد اما تعریف کردن خصوصیات بدین شکل کار خسته کننده ای است. تصور کنید که 10 خصوصیت مختلف داشته باشید و بخواهیم به شکل بالا برای هر کدام یک خصوصیت computed تعریف کنیم و آن را از store.js بگیریم. اگر روشی وجود داشت که این فرآیند را به صورت خودکار انجام دهد کار ما بسیار راحت تر می شد...

خوشبختانه پکیج VueX این قابلیت را در خود دارد که این کار را به صورت اتوماتیک انجام بدهد. تابعی کمکی به نام mapGetters در پکیج VueX وجود دارد که به ما اجازه می دهد بدون تعریف کردن خصوصیات computed در کامپوننت ها، به طور مستقیم از مقادیر state در آن ها استفاده کنیم. برای استفاده از این تابع کمکی ابتدا باید آن را در کامپوننت مورد نظر خود وارد کنید. من آن را در فایل AnotherResult.vue وارد می کنم:

<script>
import { mapGetters } from "vuex";
export default {
  computed: {
    counter() {
      return this.$store.getters.doubleCounter;
    },
    clicks() {
      return this.$store.getters.stringCounter;
    }
  }
};
</script>

در مرحله بعد باید تمام خصوصیات computed خود را حذف کنیم (دیگر به آن ها نیاز نداریم) و به جای آن می گوییم:

<script>
import { mapGetters } from "vuex";
export default {
  computed: mapGetters(["doubleCounter", "stringCounter"])
};
</script>

همانطور که می بینید من در ابتدا mapGetters را به computed پاس داده ام. mapGetters یک آرایه می گیرد که باید در آن، نامِ getter های مورد نظرتان را قرار دهید (فقط getter هایی که می خواهید از آن ها استفاده کنید، مجبور نیستید همه را وارد کنید). من می خواهم از هر دو getter خودم استفاده کنم بنابراین هر دو را به صورت اعضای رشته ای به این آرایه پاس داده ام. حالا می توانیم در قسمت template، از این getter ها به عنوان خصوصیات عادی استفاده کنیم:

<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>

اگر بخواهید نام دیگری برای خصوصیات خود تعریف کنید تا با نام getter ها یکی نباشند باید به جای آرایه، یک شیء را پاس بدهید:

<template>
  <div>
    <p>Counter is: {{ myCounter }}</p>
    <p>Number of Clicks: {{ myClicks }}</p>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
export default {
  computed: mapGetters({
    myCounter: "doubleCounter",
    myClicks: "stringCounter"
  })
};
</script>

همانطور که می بینید در اینجا یک شیء پاس داده شده است که نام های myCounter و myClicks را دارد. این نام ها، نام خصوصیات computed شما خواهند بود و کاملا سلیقه ای هستند اما مقداری که به آن ها پاس داده می شود، باید دقیقا نام getter ای باشد که می خواهید از آن استفاده کنید. من این کد را به حالت قبلی برمی گردانم و از همان آرایه ها استفاده می کنم اما شما می توانید از هر کدام که خواستید استفاده کنید. از هر روشی که استفاده کنید، کدها بدون مشکل ایجاد می شوند و کار ما واقعا ساده تر شده است اما با انجام این کار دچار مشکل بزرگ تری می شویم!

در حال حاضر کل قسمت computed برابر با getter های ما است. اگر بخواهیم خودمان چند خصوصیت computed داشته باشیم که مخصوص همین کامپوننت باشند و در State نباشند باید چه کار کنیم؟ در قسمت بعدی راجع به این مشکل صحبت خواهیم کرد.

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

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