اعمال two-way-binding در VueX

Applying two-way-binding in VueX

0
45
Vue.JS 2: اعمال two-way-binding در VueX - قسمت 97

در جلسه قبل پس از ارائه خلاصه ای کوتاه از جلسات، به بحث two-way-binding پرداختیم. مشکلی که در جلسه قبل معرفی شد، تغییر state توسط کاربر و یک input ساده بود. ما از فصل های اول این دوره یاد گرفته ایم که می توانیم با استفاده از v-model یک خصوصیت و یک input را به هم متصل کنیم تا با تغییر هر کدام، دیگری نیز تغییر کند اما مشکل جدید اینجاست که نمی توانیم خصوصیت computed خود را به روز رسانی کنیم. خصوصیت computed ما به نام value (فایل app.vue):

export default {
  computed: {
    value() {
      return this.$store.getters.value;
    }
  },
  components: {
    appCounter: Counter,
    appAnotherCounter: AnotherCounter,
    appResult: Result,
    appAnotherResult: AnotherResult
  }
};

input ساده ما در template (فایل app.vue):

<div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3">
  <h1>Vuex</h1>
  <app-result></app-result>
  <app-another-result></app-another-result>
  <hr />
  <app-counter></app-counter>
  <app-another-counter></app-another-counter>
  <hr />
  <input type="text" v-model="value" />
  <p>{{ value }}</p>
</div>

راه های مختلفی برای حل این مشکل وجود دارد که من یکی از آن ها را به شما نشان می دهم. در ابتدا باید input خود را از حالت v-model در بیاوریم چرا که نمی توانیم با خصوصیت computed یک رابطه two-way-binding را راه بیندازیم. به جای آن Value عادی را قرار داده و سپس یک رویداد input را برایش تعریف می کنیم:

<div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3">
  <h1>Vuex</h1>
  <app-result></app-result>
  <app-another-result></app-another-result>
  <hr />
  <app-counter></app-counter>
  <app-another-counter></app-another-counter>
  <hr />
  <input type="text" :value="value" @input="updateValue" />
  <p>{{ value }}</p>
</div>

امیدوارم رویداد input را از فصل های اول این دوره آموزشی به یاد داشته باشید. input@ یک event listener است که هنگام تایپ شدن، فعال می شود. با این کار گفته ام که در هنگام به روز رسانی input (تایپ مقدار جدید یا حذف مقدار قبلی) متد updateValue را اجرا کن.

در مرحله بعدی باید methods را در این کامپوننت تعریف کنیم. سپس در این قسمت متدی را با نام دلخواه خودمان تعریف می کنیم. توجه داشته باشید که متد های این قسمت همگی از متد های همین کامپوننت هستند و فعلا ربطی به state یا جای دیگری ندارند:

export default {
  computed: {
    value() {
      return this.$store.getters.value;
    }
  },
  methods: {
    updateValue() {
      
    }
  },
  components: {
    appCounter: Counter,
    appAnotherCounter: AnotherCounter,
    appResult: Result,
    appAnotherResult: AnotherResult
  }
};
</script>

قبل از اینکه من جواب را بگویم، سعی کنید حدس بزنید که درون updateValue (یا هر نامی که شما برای متد خود انتخاب کرده اید) چه کدهایی را باید بنویسیم.

// بقیه کدها //
methods: {
  updateValue(event) {
    this.$store.dispatch("updateValue", event.target.value);
  }
}
// بقیه کدها //

همانطور که در فصل های اول توضیح داده بودم، شیء event به صورت خودکار توسط Vue پاس داده می شود. تنها کاری که ما در این متد انجام داده ایم، dispatch کردن یک action به نام updateValue است. البته باید payload را هم به همراه این action ارسال کنیم بنابراین مقدار event.target.value را به عنوان payload انتخاب کرده ام که در واقع همان مقدار تایپ شده درون input ما است. حالا اگر به مرورگر برویم، با تایپ در input می بینیم که مقدار value در state نیز به روز رسانی می شود (همان مقداری که در <p> نمایش می دهیم).

آیا واقعا این تنها روش انجام این کار است؟ آیا روش بهتری وجود ندارد؟ خوشبختانه روش دیگری نیز وجود دارد! چیزی که تا به حال در مورد آن توضیح نداده بودیم، این است که خصوصیات computed می توانند getter و setter داشته باشند. من تا این قسمت در مورد آن ها حرفی نزده بودم چرا که واقعا به ندرت به آن ها احتیاج پیدا می کنید و منتظر فرصتی بودم که بتوانم آن ها را معرفی کنم. برای شروع باید input را به شکل زیر تغییر دهیم:

<input type="text" v-model="value" />
<p>{{ value }}</p>

یعنی دوباره از v-model استفاده می کنیم تا یک رابطه two-way-binding برقرار شود. حالا برای اضافه کردن getter و Setter به یک خصوصیت computed باید به شکل زیر عمل کنیم:

export default {
  computed: {
    value: {
      get() {
        return this.$store.getters.value;
      },
      set(value) {
        this.$store.dispatch("updateValue", value);
      }
    }
  },
  // methods: {
  //   updateValue(event) {
  //     this.$store.dispatch("updateValue", event.target.value);
  //   }
  // },
  components: {
    appCounter: Counter,
    appAnotherCounter: AnotherCounter,
    appResult: Result,
    appAnotherResult: AnotherResult
  }
};
</script>

به زبان ساده باید در computed نام خصوصیت خود را بیاورید (value) و سپس یک شیء را به آن پاس بدهید. شیء پاس داده شده یک متد به نام get (دریافت اطلاعات) و یک متد به نام Set (ثبت یا ویرایش اطلاعات) دارد و نمی توانید نام این متد ها را تغییر بدهید. متد set یک آرگومان را به صورت خودکار دریافت می کند که همان مقدار جدید برای value می باشد. در واقع v-model باعث می شود که مقادیر تایپ شده به عنوان یک آرگومان به متد set ارسال شوند. من action مورد نظر خودم را dispatch کرده و آرگومان پاس داده شده را به عنوان payload قرار داده ام. در نهایت کدهای methods را کامنت کرده ام تا تصور نکنید برنامه ما از آن ها استفاده می کند.

حالا کدها را ذخیره کرده و به مرورگر می رویم. اگر همه چیز را درست انجام داده باشید، با تایپ یک مقدار در input، مقدار value (در State) ما نیز به روز رسانی می شود. به طور مثال به تصویر زیر نگاه کنید:

two way binding به خوبی بین input و state کار می کند
two way binding به خوبی بین input و state کار می کند

بله! ما می توانیم رشته را نیز به این input بدهیم چرا که هیچ قانون خاصی را برایش تعیین نکرده ایم. با این حساب value ما در State برابر با roxo.ir می باشد! اگر می خواهید فقط از اعداد استفاده کنید باید تایپ input را روی number بگذارید:

<input type="number" v-model="value" />

همچنین می توانید از isNaN (متد جاوا اسکریپتی است و به Vue ربطی ندارد) استفاده کنید تا مطمئن شوید مقدار تایپ شده عدد است:

if (isNaN(YourValue)) {
  alert("The input is not a number");
  return false;
}

به جای YourValue باید مقدار input را قرار بدهید. بنابراین همه چیز به خودتان مربوط می شود. البته ما در فصل های آینده به سراغ اعتبارسنجی فرم ها در Vue.js می رویم و این موضوع را مفصلا در آنجا بررسی خواهیم کرد.

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

ارسال دیدگاه

لطفا دیدگاه خود را وارد کنید!
نام خود را وارد کنید