Event Handling
Lắng nghe DOM event bằng v-on. Trong AEM, đây là cách xử lý tương tác trên UI Vue mount lên DOM mà HTL render: click button, submit form, gõ input, đóng/mở panel.
v-on và cú pháp rút gọn
v-on:event lắng nghe một DOM event. Rút gọn bằng @.
<button v-on:click="onClick">Click</button>
<!-- rút gọn, dùng phổ biến hơn -->
<button @click="onClick">Click</button>
Inline handler vs method handler
Logic ngắn viết thẳng (inline). Logic phức tạp tách thành method.
<!-- inline: biểu thức ngắn -->
<button @click="counter += 1">Add 1</button>
<!-- method: truyền tên method, không có ngoặc -->
<button @click="greet">Greet</button>
<!-- method có tham số: gọi kèm ngoặc -->
<button @click="say('hi')">Say hi</button>
methods: {
greet(event) {
// truyền tên method thì handler nhận native event làm tham số đầu
console.log(this.name, event.target.tagName)
},
say(message) {
console.log(message)
}
}
Khi truyền tên method (không ngoặc), Vue tự truyền native DOM event vào tham số đầu tiên. Khi gọi có ngoặc, phải tự truyền event nếu cần.
Truy cập native event với $event
Cần cả tham số tùy chỉnh lẫn native event trong inline handler thì dùng biến đặc biệt $event.
<button @click="warn('Chưa submit được', $event)">Submit</button>
methods: {
warn(message, event) {
if (event) event.preventDefault()
console.log(message)
}
}
Event modifiers
Thay vì gọi event.preventDefault() / event.stopPropagation() trong method, dùng modifier để giữ method chỉ lo data logic.
<!-- chặn reload trang khi submit form -->
<form @submit.prevent="onSubmit"></form>
<!-- chặn nổi bọt sự kiện -->
<a @click.stop="doThis"></a>
<!-- chain nhiều modifier -->
<a @click.stop.prevent="doThat"></a>
<!-- chỉ dùng modifier, không cần handler -->
<form @submit.prevent></form>
Thứ tự modifier quan trọng vì code sinh ra theo đúng thứ tự. @click.prevent.self chặn mọi click, còn @click.self.prevent chỉ chặn click trên chính phần tử.
Không dùng .passive chung với .prevent: .prevent sẽ bị bỏ qua.
Key modifiers
Lọc theo phím khi nghe keyboard event. Dùng tên phím từ KeyboardEvent.key chuyển sang kebab-case.
<!-- chỉ submit khi nhấn Enter -->
<input @keyup.enter="submit">
<!-- phím PageDown -->
<input @keyup.page-down="onPageDown">
System modifier keys
Chỉ chạy handler khi đang giữ phím hệ thống: .ctrl, .alt, .shift, .meta (meta là Windows key trên Windows, Command trên Mac).
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
<!-- Alt + C -->
<input @keyup.alt.67="clear">
.exact kiểm soát chính xác tổ hợp phím:
<!-- chạy kể cả khi giữ thêm Alt/Shift -->
<button @click.ctrl="onClick">A</button>
<!-- chỉ chạy khi đúng Ctrl, không phím nào khác -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- chỉ chạy khi không giữ phím hệ thống nào -->
<button @click.exact="onClick">A</button>
Mouse button modifier: .left, .right, .middle.
Tips cho AEM
Vue mount lên DOM HTL render sẵn, event handler hoạt động bình thường trên cây component đó.
<!-- HTL mount point -->
<div id="filter-bar" data-endpoint="${model.searchEndpoint}"></div>
new Vue({
el: '#filter-bar',
data() {
return {
endpoint: this.$el.dataset.endpoint,
keyword: ''
}
},
methods: {
onSearch() {
// gọi API tới endpoint cấu hình từ dialog
console.log('search', this.keyword, this.endpoint)
}
}
})
<!-- template Vue -->
<form @submit.prevent="onSearch">
<input v-model="keyword" @keyup.enter="onSearch">
<button type="submit">Tìm</button>
</form>
Lưu ý: chỉ gắn event lên phần tử nằm trong cây Vue đã mount. Phần HTML do HTL render ngoài mount point không nhận được v-on, cần xử lý bằng JS thuần hoặc đưa vào trong component.