رویداد های کامپوننت
این صفحه فرض می کند که شما از قبل اصول اولیه کامپوننت ها را خوانده اید. اگر در مبحث کامپوننت ها تازه وارد هستید اول آن را مطالعه کنید .
اِمیت کردن و گوش دادن به رویدادها
یک کامپوننت میتواند رویدادهای سفارشی را مستقیماً در عبارات تمپلیت (مثلاً در کنترلکننده «v-on») با استفاده از روش «$emit» نهادینه شده منتشر کند:
template
<!-- MyComponent -->
<button @click="$emit('someEvent')">click me</button>
والد بعدا می تواند با استفاده از v-on
به آن گوش دهد:
template
<MyComponent @some-event="callback" />
پیراینده .once
در شنوندگان رویداد(event listeners) کامپوننت نیز پشتیبانی میشود:
template
<MyComponent @some-event.once="callback" />
مانند کامپوننتها و پراپ ها، نام رویدادها یک تغییر حالت خودکار را ایجاد میکنند. توجه کنید که ما یک رویداد camelCase را منتشر کردیم، اما میتوانیم آن را با استفاده از شنونده kebab-cased در والد گوش دهیم. مانند props casing، توصیه میکنیم از شنوندههای رویداد kebab-cased در تمپلیت ها استفاده کنید.
TIP
بر خلاف رویدادهای DOM بومی، رویدادهای اِمیت شده کامپوننت حباب نمیشوند. شما فقط می توانید به رویدادهای منتشر شده توسط یک کامپوننت مستقیم فرزند گوش دهید. اگر نیاز به برقراری ارتباط بین کامپوننت های خواهر و برادر یا کامپوننت های عمیق تو در تو وجود دارد، از یک گذرگاه رویداد خارجی یا یک راه حل مدیریت state همگانی استفاده کنید.
آرگومان های رویداد
گاهی اوقات انتشار یک مقدار خاص همراه با یک رویداد مفید است. به عنوان مثال، ممکن است بخواهیم کامپوننت <BlogPost>
مسئول میزان بزرگنمایی متن باشد. در این موارد، میتوانیم آرگومانهای اضافی را به $emit
ارسال کنیم تا این مقدار را ارائه کنیم:
template
<button @click="$emit('increaseBy', 1)">
Increase by 1
</button>
سپس، هنگامی که به رویداد در والد گوش می دهیم، می توانیم از یک تابع پیکان درون خطی به عنوان شنونده استفاده کنیم که به ما امکان می دهد به آرگومان رویداد دسترسی پیدا کنیم:
template
<MyButton @increase-by="(n) => count += n" />
یا اگر کنترل کننده رویداد(event handler) یک متد باشد:
template
<MyButton @increase-by="increaseCount" />
سپس مقدار به عنوان اولین پارامتر آن متد ارسال می شود:
js
function increaseCount(n) {
count.value += n
}
TIP
همه آرگومان های اضافی پس از اینکه نام رویداد به شنونده ارسال می شود به $emit()
ارسال می شوند . برای مثال، با $emit('foo', 1, 2, 3)
تابع شنونده سه آرگومان دریافت خواهد کرد.
اعلام رویدادهای اِمیت شده
یک کامپوننت به صراحت می تواند رویدادهایی را که اِمیت می کند با استفاده از ماکرو defineEmits()
اعلام کند :
vue
<script setup>
defineEmits(['inFocus', 'submit'])
</script>
روش $emit
که در <template>
استفاده کردیم، در بخش <script setup>
یک کامپوننت قابل دسترسی نیست، اما defineEmits()
یک تابع معادل را برمیگرداند که میتوانیم به جای آن از آن استفاده کنیم:
vue
<script setup>
const emit = defineEmits(['inFocus', 'submit'])
function buttonClick() {
emit('submit')
}
</script>
ماکرو defineEmits()
نمیتواند در داخل یک تابع استفاده شود، باید مستقیماً در <script setup>
قرار گیرد، مانند مثال بالا.
اگر از یک تابع setup
صریح به جای <script setup>
استفاده میکنید، رویدادها باید با استفاده از گزینه emits
اعلان شوند و تابع emit
در زمینه setup()
نمایش داده شود:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, ctx) {
ctx.emit('submit')
}
}
همانند سایر ویژگی های زمینه setup()
، emit
(destructured) را می توان با خیال راحت جداسازی کرد:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, { emit }) {
emit('submit')
}
}
گزینه emits
همچنین از یک نحو شی(object syntax) پشتیبانی میکند، که به ما اجازه میدهد اعتبار سنجی محموله(payload) رویدادهای اِمیت شده را در زمان اجرا (runtime) فراهم کنیم:
vue
<script setup>
const emit = defineEmits({
submit(payload) {
// مقدار `true` یا `false` را برای نشان دادن
// اعتبارسنجی موفقیت آمیز / شکست خورده برمی گرداند
}
})
</script>
اگر از TypeScript با <script setup>
استفاده میکنید، میتوانید رویدادهای منتشر شده را با استفاده از حاشیهنویسیهای نوع خالص (pure type annotations) اعلام کنید:
vue
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
</script>
جزئیات بیشتر: Typing Component Emits
اگر چه اختیاری است، پیشنهاد می شود همه رویدادهای اِمیت شده را تعریف کنید تا نحوه کار یک کامپوننت را بهتر مستند کنید. همچنین به Vue اجازه می دهد شنوندگان (listeners) شناخته شده را از fallthrough attributes حذف کند، از موارد لبه ناشی از رویدادهای DOM که به صورت دستی توسط کد شخص ثالث ارسال می شوند، اجتناب می کند.
TIP
اگر یک رویداد بومی (مثلاً click
) در گزینه emits
تعریف شده باشد، شنونده اکنون فقط به رویدادهای click
منتشر شده از کامپوننت گوش می دهد و دیگر به رویدادهای click
بومی پاسخ نمی دهد.
اعتبارسنجی رویدادها
مشابه اعتبارسنجی نوع prop، یک رویداد اِمیت شده می تواند اعتبار سنجی شود اگر به جای نحو آرایه با نحو شی تعریف شده باشد.
برای افزودن اعتبارسنجی، به رویداد تابعی اختصاص داده میشود که آرگومانهای ارسال شده به فراخوانی emit
را دریافت میکند و برای نشان دادن معتبر بودن یا نبودن رویداد، یک boolean برمیگرداند.
vue
<script setup>
const emit = defineEmits({
// بدون اعتبارسنجی
click: null,
// اعتبارسنجی رویداد submit
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Invalid submit event payload!')
return false
}
}
})
function submitForm(email, password) {
emit('submit', { email, password })
}
</script>