在Vue.js中,可以使用v-on指令监听DOM事件,并在触发时执行一些JavaScript代码。
<!-- 内联事件处理 -->
<button v-on:click="counter += 1">增加 1</button>
<!-- 使用方法事件处理 -->
<button v-on:click="greet">问候</button>
<!-- 简写形式 -->
<button @click="greet">问候</button>
内联事件处理器适用于简单的逻辑:
<div id="inline-handler-example">
<button @click="count++">
点击次数: {{ count }}
</button>
<button @click="sayHello('Vue.js')">
打招呼
</button>
</div>
<script>
new Vue({
el: '#inline-handler-example',
data: {
count: 0
},
methods: {
sayHello(name) {
alert('你好, ' + name + '!');
}
}
});
</script>
对于复杂的事件处理逻辑,推荐使用方法事件处理器:
<div id="method-handler-example">
<button @click="handleClick">
点击我
</button>
<button @click="handleEvent($event, '额外参数')">
带参数的事件
</button>
</div>
<script>
new Vue({
el: '#method-handler-example',
methods: {
handleClick() {
// 访问原生DOM事件
console.log('按钮被点击了!');
},
handleEvent(event, extraParam) {
// event是原生DOM事件
console.log('事件类型:', event.type);
console.log('额外参数:', extraParam);
console.log('点击的元素:', event.target.tagName);
}
}
});
</script>
$event访问原始的DOM事件对象。
Vue.js提供了事件修饰符来处理DOM事件的细节:
| 修饰符 | 描述 | 示例 |
|---|---|---|
.stop |
阻止事件冒泡 | @click.stop="doThis" |
.prevent |
阻止默认行为 | @submit.prevent="onSubmit" |
.capture |
使用事件捕获模式 | @click.capture="doThis" |
.self |
仅当事件在元素本身触发时调用 | @click.self="doThat" |
.once |
事件只触发一次 | @click.once="doThis" |
.passive |
用于移动端滚动性能优化 | @scroll.passive="onScroll" |
<!-- 阻止单击事件继续传播 -->
<div @click="handleOuterClick">
<button @click.stop="handleInnerClick">内部按钮</button>
</div>
<!-- 提交事件不再重载页面 -->
<form @submit.prevent="handleSubmit">
<input type="text" v-model="username">
<button type="submit">提交</button>
</form>
<!-- 修饰符可以串联 -->
<a @click.stop.prevent="doThat">链接</a>
<!-- 只有修饰符 -->
<form @submit.prevent>
<!-- 表单提交不会刷新页面 -->
</form>
Vue.js允许为v-on在监听键盘事件时添加按键修饰符:
<!-- 按键码 -->
<input @keyup.13="submit">
<!-- 按键别名 -->
<input @keyup.enter="submit">
<input @keyup.tab="nextField">
<input @keyup.delete="deleteItem">
<input @keyup.esc="cancel">
<input @keyup.space="playPause">
<!-- 方向键 -->
<input @keyup.up="moveUp">
<input @keyup.down="moveDown">
<input @keyup.left="moveLeft">
<input @keyup.right="moveRight">
<!-- 组合示例 -->
<input v-model="message"
@keyup.enter="submitForm"
@keyup.esc="clearForm">
.enter、.tab、.delete、.esc、.space、.up、.down、.left、.right
系统修饰键可以实现组合按键的功能:
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">按住Ctrl点击</div>
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear">
<!-- Shift + Click -->
<button @click.shift="handleShiftClick">按住Shift点击</button>
<!-- Ctrl + S -->
<div @keydown.ctrl.s="saveContent">
按Ctrl+S保存
</div>
<!-- .exact修饰符 -->
<button @click.exact="onClick">只有点击,没有其他键</button>
<button @click.ctrl.exact="onCtrlClick">只有Ctrl+点击</button>
限制特定的鼠标按钮触发事件:
<!-- 左键点击 -->
<button @click.left="leftClick">左键</button>
<!-- 右键点击 -->
<button @click.right="rightClick">右键</button>
<div @contextmenu.prevent="showContextMenu">
右键点击显示菜单
</div>
<!-- 中键点击 -->
<button @click.middle="middleClick">中键</button>
<!-- 阻止右键菜单默认行为 -->
<div @contextmenu.prevent>
右键不会显示浏览器菜单
</div>
下面是一个综合的事件处理示例:
<div id="event-example">
<!-- 计数器 -->
<div class="mb-3">
<button @click="increment" class="btn btn-primary me-2">
增加 (+)
</button>
<button @click="decrement" class="btn btn-secondary me-2">
减少 (-)
</button>
<span class="badge bg-info">计数: {{ count }}</span>
</div>
<!-- 表单处理 -->
<form @submit.prevent="handleSubmit" class="mb-3">
<div class="mb-2">
<input type="text"
v-model="username"
@keyup.enter="submitForm"
placeholder="按Enter键提交"
class="form-control">
</div>
<button type="submit" class="btn btn-success me-2">
提交表单
</button>
<button type="button" @click="resetForm" class="btn btn-warning">
重置
</button>
</form>
<!-- 鼠标事件 -->
<div @mouseenter="highlight = true"
@mouseleave="highlight = false"
:class="{ 'bg-warning': highlight }"
class="p-3 border rounded mb-3">
鼠标移入移出效果
</div>
<!-- 事件详情显示 -->
<div class="alert alert-secondary">
<h6>最近事件:</h6>
<ul>
<li v-for="event in recentEvents">{{ event }}</li>
</ul>
</div>
</div>
<script>
new Vue({
el: '#event-example',
data: {
count: 0,
username: '',
highlight: false,
recentEvents: []
},
methods: {
increment() {
this.count++;
this.logEvent('增加计数');
},
decrement() {
this.count--;
this.logEvent('减少计数');
},
handleSubmit() {
if (this.username.trim()) {
alert('提交用户名: ' + this.username);
this.logEvent('提交表单: ' + this.username);
}
},
submitForm() {
this.handleSubmit();
},
resetForm() {
this.username = '';
this.logEvent('重置表单');
},
logEvent(eventName) {
const time = new Date().toLocaleTimeString();
this.recentEvents.unshift(`[${time}] ${eventName}`);
// 只保留最近的5个事件
if (this.recentEvents.length > 5) {
this.recentEvents.pop();
}
}
}
});
</script>
.prevent防止表单默认提交行为.passive修饰符优化滚动性能$event参数访问原始事件对象