Appearance
Component Events
Phát và Nghe Sự Kiện
Một thành phần có thể phát sự kiện tùy chỉnh trực tiếp trong biểu thức template (ví dụ trong một trình xử lý v-on
) bằng cách sử dụng phương thức tích hợp $emit
:
template
<!-- MyComponent -->
<button @click="$emit('someEvent')">click me</button>
Bên cha sau đó có thể lắng nghe nó bằng cách sử dụng v-on
:
template
<MyComponent @some-event="callback" />
Chỉ thị .once
cũng được hỗ trợ trên bộ lọc sự kiện của thành phần:
template
<MyComponent @some-event.once="callback" />
Giống như thành phần và props, tên sự kiện cung cấp một chuyển đổi chữ tự động. Chú ý rằng chúng ta đã phát một sự kiện camelCase, nhưng có thể lắng nghe nó bằng một trình lắng nghe viết hoa chữ thường (kebab-case) ở phần cha. Như với việc chuyển đổi chữ của props, chúng tôi khuyến khích sử dụng trình lắng nghe sự kiện viết hoa chữ thường trong các template.
TIP
Không giống như sự kiện DOM nguyên bản, sự kiện phát ra từ thành phần không lan truyền. Bạn chỉ có thể lắng nghe sự kiện phát ra từ một thành phần con trực tiếp. Nếu có nhu cầu giao tiếp giữa các thành phần anh chị em hoặc sâu nhút, hãy sử dụng một bus sự kiện ngoại vi hoặc một giải pháp quản lý trạng thái toàn cục.
Đối số Sự Kiện
Đôi khi, việc phát một giá trị cụ thể với sự kiện là hữu ích. Ví dụ, chúng ta có thể muốn thành phần <BlogPost>
chịu trách nhiệm về cách làm cho văn bản lớn hơn bao nhiêu. Trong những trường hợp đó, chúng ta có thể truyền thêm đối số cho $emit
để cung cấp giá trị này:
template
<button @click="$emit('increaseBy', 1)">
Tăng thêm 1
</button>
Sau đó, khi chúng ta lắng nghe sự kiện ở phần cha, chúng ta có thể sử dụng một hàm mũi tên trực tiếp làm lắng nghe, cho phép chúng ta truy cập đối số sự kiện:
template
<MyButton @increase-by="(n) => count += n" />
Hoặc, nếu bộ xử lý sự kiện là một phương thức:
template
<MyButton @increase-by="increaseCount" />
Thì giá trị sẽ được chuyển làm tham số đầu tiên của phương thức đó:
js
function increaseCount(n) {
count.value += n
}
TIP
Tất cả các đối số thêm được truyền vào $emit()
sau tên sự kiện sẽ được chuyển tiếp đến lắng nghe. Ví dụ, với $emit('foo', 1, 2, 3)
, hàm lắng nghe sẽ nhận ba đối số.
Khai Báo Sự Kiện Phát Ra
Một thành phần có thể rõ ràng khai báo các sự kiện nó sẽ phát ra bằng cách sử dụng macro defineEmits()
:
vue
<script setup>
defineEmits(['inFocus', 'submit'])
</script>
Phương thức $emit
mà chúng ta đã sử dụng trong <template>
không thể truy cập được trong phần <script setup>
của một thành phần, nhưng defineEmits()
trả về một hàm tương đương mà chúng ta có thể sử dụng:
vue
<script setup>
const emit = defineEmits(['inFocus', 'submit'])
function buttonClick() {
emit('submit')
}
</script>
Macro defineEmits()
không thể được sử dụng bên trong một hàm, nó phải được đặt trực tiếp trong <script setup>
, như ví dụ trên.
Nếu bạn đang sử dụng một hàm setup
rõ ràng thay vì <script setup>
, sự kiện nên được khai báo bằng cách sử dụng tùy chọn emits
, và hàm emit
được tiết lộ trong ngữ cảnh của setup()
:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, ctx) {
ctx.emit('submit')
}
}
Tương tự như với các thuộc tính khác của ngữ cảnh setup()
, emit
có thể an toàn được giải đó:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, { emit }) {
emit('submit')
}
}
Tùy chọn emits
và macro defineEmits()
cũng hỗ trợ cú pháp đối tượng. Nếu bạn đang sử dụng TypeScript, bạn có thể đặt kiểu cho các đối số, điều này cho phép chúng ta thực hiện kiểm tra chạy thời gian của dữ liệu của sự kiện phát ra:
vue
<script setup>
const emit = defineEmits({
submit(payload: { email: string, password: string }) {
// return `true` or `false` để chỉ ra
// pass / fail kiểm tra hợp lệ
}
})
</script>
Nếu bạn đang sử dụng TypeScript với <script setup>
, cũng có thể khai báo các sự kiện phát ra bằng cách sử dụng các chú thích kiểu thuần túy:
vue
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
</script>
Thông tin chi tiết hơn: Kiểu Các Sự Kiện Của Thành Phần
Mặc dù không bắt buộc, nhưng khuyến nghị khai báo tất cả các sự kiện phát ra để tài liệu hóa cách một thành phần nên hoạt động. Nó cũng cho phép Vue loại bỏ các nghe sự kiện đã biết khỏi [các thuộc tính truyền xuống](/guide/components
/attrs#v-on-listener-inheritance), tránh các tình huống lạc lõng do sự kiện DOM được phát bằng cách thủ công bởi mã của bên thứ ba.
TIP
Nếu một sự kiện nguyên bản (ví dụ: click
) được định nghĩa trong tùy chọn emits
, bộ lắng nghe sẽ chỉ lắng nghe các sự kiện click
do thành phần phát ra và không còn phản hồi cho sự kiện click
nguyên bản nữa.
Kiểm Tra Sự Kiện
Tương tự như việc kiểm tra kiểu prop, một sự kiện phát ra cũng có thể được kiểm tra nếu nó được định nghĩa với cú pháp đối tượng thay vì cú pháp mảng.
Để thêm kiểm tra, sự kiện được gán một hàm nhận các đối số được truyền vào cú pháp emit
và trả về một giá trị boolean để chỉ định liệu sự kiện có hợp lệ hay không.
vue
<script setup>
const emit = defineEmits({
// Không có kiểm tra
click: null,
// Kiểm tra sự kiện submit
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Dữ liệu sự kiện submit không hợp lệ!')
return false
}
}
})
function submitForm(email, password) {
emit('submit', { email, password })
}
</script>