Appearance
用户点击按钮、输入文字、移动鼠标……这些都是"事件"。Vue 用 v-on 指令来监听这些事件。
基本用法
v-on 用于绑定事件处理函数:
vue
<template>
<button v-on:click="handleClick">点我</button>
</template>
<script>
export default {
methods: {
handleClick() {
alert('按钮被点了!')
}
}
}
</script>
v-on:click="handleClick" 的意思是:当这个按钮被点击时,调用 handleClick 方法。
简写
v-on: 太长,日常用 @ 简写:
vue
<button @click="handleClick">点我</button> <!-- 等于 v-on:click -->
<input @input="handleInput"> <!-- 等于 v-on:input -->
<form @submit="handleSubmit"> <!-- 等于 v-on:submit -->
看到 @ 就理解为"当...事件发生时"。
给方法传参
vue
<template>
<button @click="say('Hello')">打招呼</button>
<button @click="say('再见')">说再见</button>
</template>
<script>
export default {
methods: {
say(msg) {
alert(msg)
}
}
}
</script>
💡 Tip:需要事件对象怎么办? 如果你既要传参,又要拿到事件对象,用 $event:
vue
<button @click="handle('参数', $event)">点我</button>
事件修饰符
很多事件需要加上"额外操作",比如阻止表单自动提交、防止事件冒泡。Vue 提供了修饰符,在事件后面加 .xxx 就行。 | 修饰符 | 作用 | 不用 Vue 你要写 | | .prevent | 阻止默认行为(如表单提交、a 标签跳转) | e.preventDefault() | | .stop | 阻止事件冒泡(点击子元素不会触发父元素) | e.stopPropagation() | | .once | 事件只触发一次 | 手动加标志位 | | .self | 只在事件源是自身时触发 | if (e.target === e.currentTarget) | | .capture | 在捕获阶段触发 | 第三个参数 true |
vue
<template>
<!-- 表单提交时不会刷新页面 -->
<form @submit.prevent="onSubmit">
<input type="text">
<button type="submit">提交</button>
</form>
<!-- 点击"点我"不会触发灰色区域的点击事件 -->
<div @click="onOuterClick" style="background: gray; padding: 20px">
<button @click.stop="onInnerClick">点我</button>
</div>
</template>
按键修饰符
监听键盘事件时,可以指定按键:
vue
<!-- 只有按回车时触发 -->
<input @keyup.enter="onEnter">
<!-- 只有按 Esc 时触发 -->
<input @keyup.escape="onCancel">
支持的按键别名:.enter、.tab、.delete、.esc、.space、.up、.down、.left、.right 也可以直接用键码:@keyup.13(13 = 回车键码,不过用别名更直观)
组合键
vue
<!-- Ctrl + 回车 -->
<input @keyup.ctrl.enter="onCtrlEnter">
<!-- 精确匹配:只有 Ctrl 被按下(不能同时按其他键) -->
<button @click.ctrl.exact="onCtrlOnly">精确 Ctrl</button>
内联处理
简单逻辑可以直接写在模板里,不用定义方法:
vue
<template>
<button @click="count++">点了 {{ count }} 次</button>
</template>
<script>
export default {
data() {
return { count: 0 }
}
}
</script>
适合只有一行逻辑的简单操作。复杂的逻辑还是应该写到 methods 里。
实际例子:计数器
vue
<template>
<div>
<p>当前计数:{{ count }}</p>
<button @click="count++">+1</button>
<button @click="count--">-1</button>
<button @click="count = 0">重置</button>
</div>
</template>
<script>
export default {
data() {
return { count: 0 }
}
}
</script>
新手常见问题
Q:@click="fn" 和 @click="fn()" 有区别吗? A:有。@click="fn" 会把事件对象传给 fn;@click="fn()" 则什么都不传。如果不需要事件对象,两种写法效果一样。 Q:事件处理函数里怎么访问 data? A:用 this.xxx。Vue 自动把 data 里的数据挂到了 this 上。 下一步: 💡 Tip:Composition API 写法(Vue 3)
vue
<script setup>
import { ref } from 'vue'
const count = ref(0)
function handleClick() { count.value++ }
</script>
模板中的 @click 等写法完全不变。 详见: