قدرت Vue با انواع Modifierها

Impact of Modifiers on Vue Power

26 شهریور 1399
Vue.JS 2: قدرت Vue با انواع modifier ها

Event Modiferها

زمانی که با eventها کار می کنیم معمولا با مسائل ریزی روبرو می شویم که برایمان مشکل ساز هستند اما فریم ورک Vue راه حل بسیار خوبی برای آن ها است. کدهای جلسه قبل را به خاطر دارید؟ در جلسه قبل کدی نوشتیم که با حرکت موس روی یک پاراگراف، مختصات موس را به صورت عدد های x و y دریافت می کردیم. حالا تصور کنید قسمتی درون این پاراگراف وجود داشته باشد که نخواهم با حرکت موس روی آن هیچ مختصاتی دریافت کنم. بر همین اساس کدهای HTML را بدین شکل تغییر می دهم:

<div id="app">
    <button v-on:click="increase(2, $event)">Click me</button>
    <p>{{ counter }}</p>
    <p v-on:mousemove="updateCoordinates">
        Coordinates: {{ x }} / {{ y }}
        <span>DEAD SPOT</span>
    </p>
</div>

یعنی اگر موس ما روی span رفت، نمی خواهم هیچ مختصاتی دریافت کنم (DEAD SPOT به معنی «ناحیه مُرده» است). البته از آنجایی که هنوز هیچ کد جاوا اسکریپتی را برای این کار ننوشته ایم، با حرکت موس روی DEAD SPOT باز هم مختصات را دریافت می کنیم. چرا؟ به دلیل اینکه تگ Span درون تگ p است بنابراین جزئی از آن است و Event روی آن نیز اعمال می شود. بنابراین باید برای این Span یک event جداگانه تعریف کنیم:

<div id="app">
    <button v-on:click="increase(2, $event)">Click me</button>
    <p>{{ counter }}</p>
    <p v-on:mousemove="updateCoordinates">
        Coordinates: {{ x }} / {{ y }}
        <span v-on:mousemove="dummy">DEAD SPOT</span>
    </p>
</div>

من می خواهم هنگام حرکت موس روی span هیچ اتفاقی نیفتد بنابراین event آن هم باید کاری نکند، اما نمی توانیم قسمت تابع و کدهای event را خالی بگذاریم بنابراین یک تابع به نام dummy را به آن پاس داده ام. حالا می توانیم در قسمت کدهای جاوا اسکریپت این متد را به شکل زیر تعریف کنیم:

    methods: {
        increase: function (step, event) {
            this.counter += step;
        },
        updateCoordinates: function (event) {
            this.x = event.clientX;
            this.y = event.clientY;
        },
        dummy: function (event) {
            event.stopPropagation();
        }
    }

ما در این تابع event را دریافت کرده و سپس propagation را در آن غیرفعال می کنیم. با این کار مطمئن می شویم که کد تعیین شده ما به عناصر بالاتر (مثل تگ p) سرایت نمی کند. مبحث معروف event propagation یک مبحث عادی در جاوا اسکریپت است که باید با آن آشنا باشید و اختصاصی به Vue ندارد. به طور خلاصه آن را به شما یادآوری می کنم: عناصر در HTML یکدیگر را نمی پوشانند بنابراین اگر event ای را روی یک عنصر تعیین کنیم و آن را اجرا کنیم، این Event تا بالاترین سطح اجرا خواهد شد. بنابراین اگر در کد بالا از propagation جلوگیری نکنیم، کد ما برای تمام سطوح بالاتر مانند تگ p نیز اجرا می شود. برای اطلاعات بیشتر در این مورد عبارت javascript event propagation را جست و جو کنید.

حالا اگر کد بالا را اجرا کنید، مشکل ما حل شده است و با بردن موس روی DEAD SPOT آپدیت شدن مختصات متوقف می شود. این راه حل یک راه حل جاوا اسکریپتی ساده بود اما با استفاده از Vue می توانیم کار خودمان را ساده تر از این حالت انجام بدهیم. ابتدا کل تعریف تابع dummy را از قسمت کدهای جاوا اسکریپت حذف کنید. به جای آن در قسمت HTML از یک event modifier (ویرایشگر رویداد) به نام stop استفاده می کنیم:

<div id="app">
    <button v-on:click="increase(2, $event)">Click me</button>
    <p>{{ counter }}</p>
    <p v-on:mousemove="updateCoordinates">
        Coordinates: {{ x }} / {{ y }}
        <span v-on:mousemove.stop="">DEAD SPOT</span>
    </p>
</div>

Event modifier های مختلفی در Vue وجود دارد که به وقتش با آن ها آشنا می شویم (مثلا prevent کار preventDefault را انجام می دهد) اما فعلا بدانید که stop از propagation یک رویداد جلوگیری می کند. همچنین برای قسمت تابع در این event هیچ تابع یا کدی را مشخص نکرده ام (dummy را حذف کرده ایم) که یعنی این event هیچ کاری نخواهد کرد. حالا اگر کد بالا را اجرا کنید، دقیقا همان نتیجه قبلی را خواهیم داشت.

در ضمن شما می توانید event modifier ها را به هم chain (زنجیره کردن) کنید. به طور مثال:

        <span v-on:mousemove.stop.prevent="">DEAD SPOT</span>

البته در پروژه ما preventDefault کردن، کار خاصی انجام نمی دهد اما نکته اینجاست که بدانید می توان event modifier ها را به هم chain کرد.

Key Modifierها

ما نه تنها event modifier داریم بلکه خصوصیت دیگری به نام key modifier نیز داریم. برای اینکه متوجه بشوید یک فیلد input در کدهای HTML خودم قرار می دهم:

<div id="app">
    <button v-on:click="increase(2, $event)">Click me</button>
    <p>{{ counter }}</p>
    <p v-on:mousemove="updateCoordinates">
        Coordinates: {{ x }} / {{ y }}
        <span v-on:mousemove.stop.prevent="">DEAD SPOT</span>
    </p>
    <input type="text" v-on:keyup="alertMe">
</div>

Keyup یک رویداد ساده جاوا اسکریپتی است که زمان فعال شدنش برابر با زمانی است که کاربر دکمه ای را روی کیبورد رها می کند. در کد بالا با هر بار رها شدن یک کلید، تابعی به نام alertMe اجرا خواهد شد. تعریف این تابع نیز بسیار ساده است و فقط یک alert را اجرا می کند:

new Vue({
    el: '#app',
    data: {
        counter: 0,
        x: 0,
        y: 0
    },
    methods: {
        increase: function (step, event) {
            this.counter += step;
        },
        updateCoordinates: function (event) {
            this.x = event.clientX;
            this.y = event.clientY;
        },
        alertMe: function () {
            alert('Alert!');
        }
    }
})

با اجرای این کد در مرورگر، هر زمان که درون فیلد input چیزی بنویسید یک پنجره alert برایتان باز می شود. حالا فرض کنید بخواهیم کاری کنیم که فقط با زدن کلید Enter پنجره alert را ببینیم. برای این کار از یک key modifier استفاده می کنیم:

    <input type="text" v-on:keyup.enter="alertMe">

از این به بعد alert ما فقط زمانی نمایش داده می شود که دکمه enter را بزنیم. البته شما می توانید key modifier ها را نیز به هم chain کنید. مثلا:

    <input type="text" v-on:keyup.enter.space="alertMe">

کد بالا یعنی اگر کلید Enter یا کلید Space روی کیبورد فشرده و رها شود (هر کدام باشد فرقی نمی کند) تابع alertMe اجرا خواهد شد. شما می توانید لیست کاملی از event modifier ها و key modifier ها را از documentation رسمی فریم ورک Vue به آدرس زیر دریافت کنید:

https://vuejs.org/v2/guide/events.html#Event-Modifiers

نکته پایانی: همیشه یادتان باشد که حتما نیازی به اجرای تابع خاصی در این قسمت ها نیست. هر جایی که  می توانید با آن به نمونه شیء Vue خود دسترسی داشته باشید (مثلا درون {{}} یا مقدار پاس داده شده به Event ها و غیره) می توانید کدهای جاوا اسکریپتی خود را نیز بنویسید. البته دو شرط دارد: بیشتر از یک expression نباشند و همینطور دارای if statement یا حلقه های for و غیره نیز نباشند. به مثال زیر توجه کنید:

    <button v-on:click="increase(2, $event)">Click me</button>

کد بالا وظیفه اضافه کردن تعداد counter را داشت. حالا فرض کنید بخواهیم فقط یک واحد به counter اضافه کنیم. در چنین حالتی می گوییم:

    <button v-on:click="counter++">Click me</button>

یعنی مستقیما می توانیم به counter دسترسی داشته باشیم. همین مسئله را برای String interpolation نیز می توانیم انجام بدهیم:

    <p>{{ counter * 2 }}</p>

این کد نیز صحیح است.

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

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

houman amani
19 بهمن 1399
من به مطالعه خیلی علاقه دارم و همیشه خواندن برایم بازدهی بیشتری نسبت به ویدیو دیدن دارد ممنون بابت مقاله ی خوبی که ارائه دادید مرجع خیلی خوبیست برای یادگرفتن

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

مژگان
06 آبان 1399
واقعا عالی توضیح دادید مباحثو.ممنون

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