روش جایگزین خصوصیات Computed

Computed Properties Alternative method

26 شهریور 1399
Vue.JS 2: روش جایگزین خصوصیات computed

تا این قسمت درباره گزینه های مختلفی برای شیء Vue صحبت کرده ایم که به طور خلاصه عبارت اند از:

  • el: متصل کردن شیء به DOM.
  • data: ذخیره اطلاعاتی که بعدا استفاده خواهند شد.
  • methods: متدهایی که به آن ها نیاز داریم.
  • computed: وابستگی ها (خصوصیات وابسته).

در این جلسه می خواهیم با خصوصیت جدیدی به نام watch (در اینجا به معنای «زیر نظر گرفتن») آشنا شویم که به نوعی یک جایگزین برای computed محسوب می شود. کار اصلی watch اجرای کدهای خاص در هنگام تغییر داده ها است. در Computed ما خصوصیات خودمان را مانند data تعریف می کردیم، البته منطق آن را درون یک تابع قرار می دادیم اما watch نام خصوصیت را دریافت کرده و آن را زیر نظر می گیرد. مثلا:

new Vue({
    el: '#app',
    data: {
        counter: 0,
        secondCounter: 0
    },
    computed: {
        output: function () {
            console.log('Computed');
            return this.counter > 5 ? 'Greater than 5' : 'Smaller than 5';
        }
    },
    watch: {
        counter: function (value) {

        }
    },
    methods: {
        result: function () {
            console.log('Method');
            return this.counter > 5 ? 'Greater than 5' : 'Smaller than 5';
        }
    }
})

همانطور که گفتم در Watch باید نام یکی از خصوصیات خود را پاس بدهید. من counter را انتخاب کرده ام (نام خصوصیت درون watch دقیقا باید مانند نام آن در data باشد). Value نیز مقدار تغییری است که قرار است در آینده ایجاد شود و به صورت خودکار توسط Vue به ما پاس داده می شود. بنابراین خلاصه Watch این است که ما خصوصیتی را زیر نظر می گیریم و در صورتی که تغییر کرد، تابع مربوط به آن در watch اجرا خواهد شد. Value نیز مقدار تغییر کرده (پس از ایجاد تغییر) می باشد. ما می توانیم کارهای زیادی را در این تابع انجام دهیم. به طور مثال می توانیم خصوصیت output را به جای تعریف در computed در watch تعریف کنیم.

نکته: توصیه می شود تا حد ممکن از computed به جای Watch استفاده کنید چرا که به طور کلی بهینه تر است (البته در برخی از موارد استفاده از Watch راه جایگزینی ندارد).

یکی از مواردی که فقط در watch امکان پذیر است، اجرای کدهای نامتقارن (asynchronous code) است چرا که خصوصیات computed همیشه به صورت متقارن (synchronous) اجرا می شوند. برای اینکه مثالی از watch را داشته باشیم، فرض کنید که بخواهیم counter ما پس از 2 ثانیه دوباره صفر شود. قبل از اینکه این کار را انجام بدهیم باید شما را با مبحث closure در جاوا اسکریپت آشنا کنم. Closure ارتباط خاصی با Vue ندارد و یکی از بحث های عادی جاوا اسکریپت است اما بسیاری از توسعه دهندگان جاوا اسکریپت با آن آشنا نیستند بنابراین بهتر است آن را به صورت خلاصه مرور کنیم.

به کد زیر توجه کنید (من انتظار دارم که با مبحث Scope متغیرها آشنا باشید):

function makeFunc() {
  var name = 'Mozilla';
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

در این کد تابعی به نام makeFunc داریم که متغیری به نام name را تعریف می کند. سپس یک تابع دیگر به نام displayName را تعریف می کند که در نهایت یک پنجره alert را به همراه متغیر name نمایش خواهد داد. همانطور که می دانید متغیرهایی که درون یک تابع تعریف شوند، Scope شان فقط درون تابع است و بیرون از تابع تعریف نشده هستند. از طرفی در بسیاری از زبان های برنامه نویسی این نوع متغیر ها که درون تابع تعریف می شوند فقط تا زمانی وجود دارند که تابع در حال اجرا شدن است و به محض تکمیل شدن اجرای تابع، از بین می روند. بنابراین اگر برنامه نویس خوبی در جاوا اسکریپت نباشید، تصور خواهید کرد که کد بالا اجرا نشده و خطا می دهد در صورتی که این کد بدون مشکل اجرا خواهد شد. چرا؟ به دلیل اینکه توابع در جاوا اسکریپت یک Closure (به معنی «بستار» یا یک محیط بسته) به وجود می آورند.

Closure یعنی توابه جاوا اسکریپت با خصوصیتی پنهان به نام [[Environment]] ایجاد می شوند که به تابع کمک می کند محلِ ساخته شدن خود را به یاد داشته باشد. یعنی تابع displayName می داند که در زمان تعریف شدن، متغیری به نام name در تابع پدر خود وجود داشته است که مقدارش برابر با Mozilla است.

تعریف فنی closure بدین شکل است:

closure is the combination of a function and the lexical environment within which that function was declared. This environment consists of any local variables that were in-scope at the time the closure was created. منبع: شبکه توسعه دهندگان موزیلا

ترجمه ساده آن می شود: بستار (closure) به مجموعه یک تابع و محیط آن گفته می شود. این محیط (محیطی که تابع در آن تعریف شده است) شامل تمام متغیر هایی است که در زمان تعریف شدن این تابع، در Scope وجود داشته اند.

حالا به کدهای خودمان برمی گردیم. من می خواهم counter پس از 2 ثانیه دوباره صفر شود بنابراین:

new Vue({
    el: '#app',
    data: {
        counter: 0,
        secondCounter: 0
    },
    computed: {
        output: function () {
            console.log('Computed');
            return this.counter > 5 ? 'Greater than 5' : 'Smaller than 5';
        }
    },
    watch: {
        counter: function (value) {
            var vm = this;
            setTimeout( function() {
                vm.counter = 0;
            }, 2000);
        }
    },
    methods: {
        result: function () {
            console.log('Method');
            return this.counter > 5 ? 'Greater than 5' : 'Smaller than 5';
        }
    }
})

اگر یادتان باشد در Vue کلید واژه this به همین شیء this برمی گردد و به ما کمک می کند که بدون صدا زدن this.data.counter یا اشکال دیگر، بگوییم this.counter و کارمان را راحت کنیم. مسئله اینجاست که توابع callback ای مانند setTimeout یک closure به حساب می آیند بنابراین باید کلیدواژه this را در یک متغیر ذخیره کنم تا وقتی درون این closure می رویم، باز هم به آن دسترسی داشته باشیم.

حالا می توانید کدها را اجرا کنید و روی دکمه increase کلیک کنید. هر زمان که کلیک کردن را برای 2 ثانیه متوقف کنید، counter دوباره صفر خواهد شد. چرا؟ به دلیل اینکه counter را در watch گذاشته ایم، بنابراین counter زیر نظر گرفته شده و هر بار که تغییر کند، تابع مربوط به آن در Watch اجرا می شود.

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

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

rahim
30 آذر 1399
سلام میشه لطف کنید منبع این اطلاعات رو قرار بدهید سایت vue رفتم ولی با مثال توضیح نداده اگه شد منبع رو هم قرار بدید با تشکر

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