آموزش Vue.js: رویدادها در Vue — بخش هشتم
Vue.js به ما امکان تفسیر رویداد DOM را با استفاده از دایرکتیو v-on روی یک عنصر میدهد. در این بخش از سری مقالات آموزش Vue به بررسی مبحث رویدادها در Vue میپردازیم. برای مطالعه بخش قبلی روی لینک زیر کلیک کنید:
اگر بخواهیم زمانی که یک رویداد کلیک در عنصری رخ میدهد، کاری انجام دهیم باید به صورت زیر عمل کنیم:
1<template>
2 <a>Click me!</a>
3</template>
یک دایرکتیو v-on اضافه میکنیم:
1<template>
2 <a v-on:click="handleClick">Click me!</a>
3</template>
Vue یک ساختار جایگزین راحتتر نیز به این منظور دارد:
1<template>
2 <a @click="handleClick">Click me!</a>
3</template>
میتوانید از پرانتزها استفاده بکنید یا نکنید. "click="handleClick@ با "()click="handleClick@ برابر است. handleClick متد متصل به کامپوننت است:
1<script>
2export default {
3 methods: {
4 handleClick: function(event) {
5 console.log(event)
6 }
7 }
8}
9</script>
آن چه در این جا باید بدانید، این است که میتوانید پارامترهایی از رویدادها به صورت زیر ارسال کنید:
@click="handleClick(param)"
و آنها درون متد دریافت میشوند.
دسترسی به شیء اصلی رویداد
در اغلب موارد میخواهیم یک اکشن را روی شیء رویداد اجرا کنیم و یا برخی مشخصههای آن را بررسی کنیم. برای دسترسی به شیء اصلی رویداد میتوانید از دایرکتیو event$ استفاده کنید:
1<template>
2 <a @click="handleClick($event)">Click me!</a>
3</template>
4
5<script>
6export default {
7 methods: {
8 handleClick: function(event) {
9 console.log(event)
10 }
11 }
12}
13</script>
و اگر از قبل متغیری ارسال کرده باشید:
1<template>
2 <a @click="handleClick('something', $event)">Click me!</a>
3</template>
4
5<script>
6export default {
7 methods: {
8 handleClick: function(text, event) {
9 console.log(text)
10 console.log(event)
11 }
12 }
13}
14</script>
از این جا به بعد میتوانید ()event.preventDefault را فراخوانی کنید، اما یک روش بهتر به نام مادیفایرهای رویداد نیز وجود دارد که در بخش بعدی در مورد آن بیشتر توضیح میدهیم:
مادیفایرهای رویداد
به جای سر و کله زدن با اشیای DOM در متدها میتوانید به Vue اعلام کنید که موارد زیر را برای شما مدیریت کند:
- click.prevent@ اقدام به فراخوانی ()event.preventDefault میکند.
- click.stop@ اقدام به فراخوانی ()event.stopPropagation میکند.
- click.passive@ از گزینه پسیو ()addEventListener استفاده میکند.
- click.capture@ به جای bubbling رویداد از کپچر کردن رویداد استفاده میکند.
- click.self@ مطمئن میشود که رویداد کلیک از یک رویداد فرزند buble نشده است، بلکه مستقیماً روی آن عنصر رخ داده است.
- click.once@ موجب میشود که رویداد دقیقاً یک بار تحریک شود.
همه این گزینهها میتوانند با الحاق یک مادیفایر به دیگری با هم ترکیب شوند.
تزریق محتوا با slot-ها
یک کامپوننت میتواند محتوای خود را به طور کامل به صورت زیر تعریف کند:
1Vue.component('user-name', {
2 props: ['name'],
3 template: '<p>Hi {{ name }}</p>'
4})
همچنین میتواند به کامپوننت والد اجازه بدهد که با استفاده از اسلات هر نوع محتوایی را درون آن تزریق کند.
اسلات چیست؟
اسلات با قرار دادن <slot></slot> در یک قالب کامپوننت تعریف میشود:
1Vue.component('user-information', {
2 template: '<div class="user-information"><slot></slot></div>'
3})
هنگامی که از این کامپوننت استفاده میکنیم، هر محتوایی که بین تگهای باز و بسته اسلات اضافه شود درون محفظه اسلات اضافه خواهد شد:
1<user-information>
2 <h2>Hi!</h2>
3 <user-name name="Flavio"></user-name>
4</user-information>
اگر هر محتوایی را درون تگهای اسلات قرار دهید به عنوان یک محتوای پیشفرض در صورت عدم ارسال چیز دیگر مورد استفاده قرار میگیرد. لیآوتهای پیچیده کامپوننت برای سازماندهی محتوا به روش بهتری نیاز دارد. به این منظور از اسلاتهای با نام استفاده میکنیم.
اسلاتهای با نام
با بهرهگیری از «اسلات با نام» میتوان بخشهایی از اسلات را به موقعیت خاصی در لیآوت قالب کامپوننت انتساب داد و از یک خصوصیت slot برای هر تگ استفاده کرد تا محتوا را به آن اسلات انتساب داد. هر چیزی خارج از تگ قالب به slot اصلی اضافه میشود. برای سهولت کار از کامپوننت تک فایلی page در این مثال استفاده میکنیم:
1<template>
2 <div>
3 <main>
4 <slot></slot>
5 </main>
6 <aside>
7 <slot name="sidebar"></slot>
8 </aside>
9 </div>
10</template>
روش استفاده از آن با ارائه محتوای اسلات در یک کامپوننت والد به صورت زیر است:
1<page>
2 <template v-slot:sidebar>
3 <ul>
4 <li>Home</li>
5 <li>Contact</li>
6 </ul>
7 </template>
8
9 <h2>Page title</h2>
10 <p>Page content</p>
11</page>
میانبر کارآمدی به صورت # نیز وجود دارد:
1<page>
2 <template #sidebar>
3 <ul>
4 <li>Home</li>
5 <li>Contact</li>
6 </ul>
7 </template>
8
9 <h2>Page title</h2>
10 <p>Page content</p>
11</page>
اسلاتهای با دامنه
در اسلات نمیتوانیم از کامپوننت والد به دادههای درون کامپوننت فرزند دسترسی پیدا کنیم. Vue این کاربرد را شناسایی کرده و روشی برای انجام این کار در اختیار ما قرار داده است:
1<template>
2 <div>
3 <main>
4 <slot v-bind:dogName="dogName"></slot>
5 </main>
6 </div>
7</template>
8
9<script>
10export default {
11 name: 'Page',
12 data: function() {
13 return {
14 dogName: 'Roger'
15 }
16 }
17}
18</script>
در کامپوننت والد میتوانیم به نام سگ که به صورت زیر ارسال شده است، دسترسی پیدا کنیم:
1<page>
2 <template v-slot="slotProps">
3 {{ slotProps.dogName }}
4 </template>
5</page>
slotProps صرفاً یک متغیر است که برای دسترسی به props ارسالی مورد استفاده قرار دادهایم. شما میتوانید یک متغیر را صرفاً برای نگهداری props که به کامپوننتهای فرزند ارسال میکنید تعریف نمایید و این کار با تجزیه درجای شیء قابل اجرا است:
1<page>
2 <template v-slot="{ dogName }">
3 {{ dogName }}
4 </template>
5</page>
فیلتر و helper برای قالب
فیلترها کارکردهایی هستند که از سوی کامپوننتهای Vue عرضه شدهاند و امکان اعمال قالببندی و تبدیلها را در هر بخشی از دادههای دینامیک قالب فراهم میسازند. فیلترها دادههای کامپوننت یا هر جزء دیگر آن را تغییر نمیدهند، بلکه تنها روی خروجی تأثیر میگذراند.
فرض کنید میخواهید یک نام را پرینت کنید:
1<template>
2 <p>Hi {{ name }}!</p>
3</template>
4
5<script>
6export default {
7 data() {
8 return {
9 name: 'Flavio'
10 }
11 }
12}
13</script>
در این بخش میخواهیم بررسی کنیم که name واقعاً شامل یک مقدار است یا نه و در صورت عدم وجود نام از عبارت there استفاده کنیم تا در خروجی جمله Hi there پرینت شود. فیلترهای زیر را وارد میکنیم:
1<template>
2 <p>Hi {{ name | fallback }}!</p>
3</template>
4
5<script>
6export default {
7 data() {
8 return {
9 name: 'Flavio'
10 }
11 },
12 filters: {
13 fallback: function(name) {
14 return name ? name : 'there'
15 }
16 }
17}
18</script>
به ساختار بهکارگیری فیلتر که به صورت | filterName است توجه کنید. اگر با Unix آشنا باشید میدانید که این یک عملگر pipe یونیکس است که برای ارسال خروجی یک عملیات به ورودی یک عملیات دیگر مورد استفاده قرار میگیرد.
مشخصه filters کامپوننت یک شیء است. یک فیلتر منفرد تابعی است که یک مقدار میپذیرد و یک مقدار دیگر بازگشت میدهد. مقدار بازگشتی همان مقداری است که در عمل در قالب Vue.js پرینت میشود. البته فیلتر به دادهها و متدهای کامپوننت دسترسی دارد. بهترین کاربرد فیلترها در موارد زیر است:
- تبدیل یک رشته برای مثال بزرگنویسی یا کوچکنویسی حروف آن.
- قالببندی یک قیمت.
در بخش قبلی مثالی از یک فیلتر به صورت زیر دیدید:
{{ name | fallback }}
زنجیرهسازی فیلترها
فیلترها میتوانند با تکرار ساختار pipe به هم زنجیر شوند:
{{ name | fallback | capitalize }}
کد فوق ابتدا fallback را اعمال میکند، سپس فیلتر capitalize اعمال میشود. فیلترهای پیشرفته نیز میتوانند با استفاده از ساختار پارامترهای تابع نرمال پارامترهایی قبول کنند:
1<template>
2 <p>Hello {{ name | prepend('Dr.') }}</p>
3</template>
4
5<script>
6export default {
7 data() {
8 return {
9 name: 'House'
10 }
11 },
12 filters: {
13 prepend: (name, prefix) => {
14 return `${prefix} ${name}`
15 }
16 }
17}
18</script>
اگر پارامترهایی را به یک فیلتر ارسال کنید، نخستین پارامتر ارسالی به تابع فیلتر همواره آیتم مورد نظر در میانیابی قالب (در مثال فوق name) خواهد بود که در ادامه آن پارامترهای صریح ارسال میشوند. با جدا کردن پارامترها به وسیله کاما میتوان چند پارامتر به فیلتر ارسال کرد.
توجه کنید که ما از یک تابع arrow استفاده کردهایم. ما به طور کلی از تابعهای arrow در متدها و مشخصههای محاسبهشده اجتناب میکنیم، زیرا آنها همواره ارجاعی به this برای دسترسی به دادههای کامپوننت دارند، اما در این مورد فیلتر نیازی به دسترسی به this ندارد بلکه دادههای مورد نیاز خود را از طریق پارامترها دریافت میکند و میتوانیم با اطمینان خاطر از ساختار تابع سادهتر arrow بهره بگیریم.
این پکیج (+) فیلترهای از پیش تعریفشده زیادی برای استفاده مستقیم در قالبها دارد که شامل capitalize ،uppercase ،lowercase ،placeholder ،truncate ،currency ،pluralize و موارد دیگر میشود. بدین ترتیب به پایان بخش هشتم از سری مقالات آموزش Vue.js میرسیم. برای مطالعه بخش بعدی روی لینک زیر کلیک کنید:
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- پنج ابزار برای توسعه سریع اپلیکیشنهای Vue.js — راهنمای کاربردی
- آموزش Vue.js: کدنویسی عملی — بخش سوم
- آموزش Vue.js: دایرکتیوها در Vue — بخش ششم
==