Bài 14: Event handling với VueJS
Mình đã cập nhật lại tất cả các bài với các thay đổi ở hiện tại ở năm 2024: Vue 3, Vite, Laravel 11x,...
Cập nhật gần nhất 08/06/2024
Hello các bạn quay trở lại với series học VueJS với Laravel của mình 👋👋
Ở bài trước mình đã hướng dẫn các bạn về cách binding form input, bài này chúng ta sẽ cùng tìm hiểu cách xử lý các sự kiện khi người dùng tương tác như click
hay bấm các phím trong VueJS nhé.
Để bắt các sự kiện này ta dùng v-on
hoặc mình thường dùng kiểu short-hand
là @
(trong bài này mình dùng cách viết shorthand
nhé).
Ở bài này nội dung khá là đơn giản và mình nghĩ nó cũng khá dễ hiểu cho các bạn, nên chúng ta sẽ chủ yếu làm qua các ví dụ để hiểu nha. 🚀🚀
Event Handling cơ bản
Sử Dụng v-on
hoặc @
Bạn có thể sử dụng v-on
hoặc ký hiệu @
để lắng nghe các sự kiện DOM.
<template>
<div>
<button @click="handleClick">Click me</button>
</div>
</template>
<script setup>
const handleClick = () => {
alert('Button clicked!');
}
</script>
Truyền tham số
Bạn có thể truyền tham số vào hàm xử lý sự kiện.
<template>
<div>
<button @click="handleClick('Hello, Vue!')">Click me</button>
</div>
</template>
<script setup>
const handleClick = (message) => {
alert(message);
}
</script>
Event Modifiers
Vue cung cấp một loạt các event modifiers để thay đổi hành vi mặc định của các sự kiện.
.stop
Ngăn chặn sự kiện lan truyền lên phần tử cha.
<template>
<div @click="handleDivClick">
<button @click.stop="handleButtonClick">Click me</button>
</div>
</template>
<script setup>
const handleDivClick = () => {
alert('Div clicked!');
}
const handleButtonClick = () => {
alert('Button clicked!');
}
</script>
.prevent
Ngăn chặn hành vi mặc định của event:
<template>
<form @submit.prevent="handleSubmit">
<input type="text" v-model="inputValue">
<button type="submit">Submit</button>
</form>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('');
const handleSubmit = () => {
alert(`Form submitted with input: ${inputValue.value}`);
}
</script>
Ở trên sau khi submit và click vào alert thì page sẽ không bị reload
.capture
Lắng nghe sự kiện trong pha capturing thay vì pha bubbling.
<template>
<div @click.capture="handleClick">
<button @click="handleButtonClick">Click me</button>
</div>
</template>
<script setup>
const handleClick = () => {
alert('Div clicked!');
}
const handleButtonClick = () => {
alert('Button clicked!');
}
</script>
Ở trên, handler của cha sẽ chạy trước của con, vì phase capturing chạy từ bên ngoài vào trong:
.self
Chỉ lắng nghe sự kiện nếu sự kiện được kích hoạt trên chính phần tử đó.
<template>
<div @click.self="handleClick">
<button>Click me</button>
</div>
</template>
<script setup>
const handleClick = () => {
alert('Div clicked!');
}
</script>
Ở đây handler sẽ chỉ được kích hoạt nếu ta trigger event trên chính nó (vùng màu đỏ), nếu ta trigger event từ button thì sẽ không có gì xảy ra:
.once
Lắng nghe sự kiện chỉ một lần duy nhất:
<template>
<button @click.once="handleClick">Click me once</button>
</template>
<script setup>
const handleClick = () => {
alert('Button clicked!');
}
</script>
.exact
exact
được sử dụng khi ta muốn thực hiện một hành động nào đó chỉ khi người dùng bấm chính xác các nút hay tổ hợp phím/chuột:
<!-- hành động bên dưới được gọi ngay cả khi các nút khác được bấm đồng thời như Alt hay Shift -->
<button @click.ctrl="onClick">A</button>
<!-- chỉ thực hiện khi bấm chính xác tổ hợp click+ctrl -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- Chỉ thực hiện khi click -->
<button @click.exact="onClick">A</button>
Kết hợp nhiều modifiers
Ta có thể kết hợp nhiều modifers cùng lúc tuỳ ý luôn nhé:
<!-- the click event's propagation will be stopped -->
<a @click.stop="doThis"></a>
<!-- the submit event will no longer reload the page -->
<form @submit.prevent="onSubmit"></form>
<!-- modifiers can be chained -->
<a @click.stop.prevent="doThat"></a>
<!-- just the modifier -->
<form @submit.prevent></form>
<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div @click.self="doThat">...</div>
Key Modifiers ⌨
Lắng nghe các sự kiện bàn phím với key modifiers.
<template>
<input @keyup.enter="handleEnter" placeholder="Press Enter">
</template>
<script setup>
const handleEnter = () => {
alert('Enter pressed!');
}
</script>
Ngoài ra Vue còn 1 loạt các modifiers khác như .tab/.delete/.esc....
Event Handling với Inline Handlers
Bạn có thể viết các hàm xử lý sự kiện trực tiếp trong template.
<template>
<button @click="() => alert('Button clicked!')">Click me</button>
</template>
Mouse Button Modifiers 🖱️
Vue 3 cung cấp một số mouse button modifiers giúp bạn dễ dàng xác định hành động dựa trên nút chuột được nhấn. Dưới đây là một số modifiers phổ biến:
.left
Lắng nghe sự kiện khi nhấn nút chuột trái (mặc định).
<template>
<button @click.left="handleLeftClick">Left Click me</button>
</template>
<script setup>
const handleLeftClick = () => {
alert('Left button clicked!');
}
</script>
.right
Lắng nghe sự kiện khi nhấn nút chuột phải.
<template>
<button @click.right="handleRightClick">Right Click me</button>
</template>
<script setup>
const handleRightClick = (event) => {
event.preventDefault(); // Ngăn chặn menu ngữ cảnh mặc định của trình duyệt
alert('Right button clicked!');
}
</script>
.middle
Lắng nghe sự kiện khi nhấn nút chuột giữa (con lăn, chú ý là các bạn phải ấn nó xuống chứ không phải cuộn nha).
<template>
<button @click.middle="handleMiddleClick">Middle Click me</button>
</template>
<script setup>
const handleMiddleClick = () => {
alert('Middle button clicked!');
}
</script>
Kết bài
Event handling trong Vue 3 mang lại cho bạn sự linh hoạt và mạnh mẽ để quản lý các tương tác người dùng. Từ việc xử lý các sự kiện DOM cơ bản, sử dụng các event modifiers, key modifiers, đến việc phát triển các custom events trong components, Vue 3 cung cấp mọi thứ bạn cần để xây dựng các ứng dụng phong phú và tương tác.
Vue còn rất nhiều loại modifiers nữa, trong bài mình chỉ nói các loại phổ biến hay dùng thôi. Các bạn có thể xem thêm ở đây nha
Ở bài tiếp theo chúng ta sẽ cùng tìm hiểu về CSS scoped
trong VueJS nhé.
Cám ơn các bạn đã theo dõi series của mình, nếu có gì thắc mắc các bạn để lại dưới comment nhé ^^!
All rights reserved