在 Vue.js 的生态系统中,用户交互是构建动态应用的关键。无论是点击按钮、提交表单,还是在输入框中键入内容,都需要通过事件监听来触发相应的逻辑。而在 Vue 2 及 Vue 3 的模板语法中,
v-on 指令正是处理这一切的核心工具。本文将带你深入了解
v-on 的作用、它的简洁写法,以及那些能极大提升开发效率的事件修饰符。一、v-on 的核心作用
v-on 指令的主要作用是监听 DOM 事件,并在事件触发时执行指定的 JavaScript 表达式或方法。简单来说,它就像是在原生的
addEventListener 之上包裹了一层 Vue 的语法糖,让事件绑定变得更加声明式和直观。当用户与页面交互(如点击、鼠标悬停、键盘按下)时,Vue 会自动调用你绑定的处理函数。基本用法
html
预览
1<!-- 完整语法 -->
2<button v-on:click="counter += 1">增加计数</button>
3
4<!-- 或者绑定一个方法 -->
5<button v-on:click="handleClick">点击我</button>
在上面的例子中,
v-on:click 告诉 Vue:“请监听这个按钮的 click 事件,一旦触发,就执行后面的表达式或方法。”二、简写形式:@ 符号
由于事件绑定在 Vue 应用中极其频繁,为了减少打字量并提高代码可读性,Vue 为
v-on 提供了一个非常流行的简写形式:@。- 完整写法:
v-on:click="handleClick" - 简写写法:
@click="handleClick"
这两种写法在功能上完全等价,编译器会将它们处理成相同的渲染逻辑。在现代 Vue 开发社区中,
@ 符号几乎是标准配置,因为它能让模板看起来更加清爽。html
预览
1<!-- 推荐写法 -->
2<form @submit.prevent="onSubmit">
3 <input @keyup.enter="search" v-model="query" />
4 <button type="submit">搜索</button>
5</form>
三、强大的事件修饰符
在处理 DOM 事件时,我们经常需要调用
event.preventDefault() 或 event.stopPropagation()。虽然可以在方法内部手动调用这些 API,但这会让业务逻辑变得杂乱,混合了“数据操作”和“DOM 细节”。Vue 提供了事件修饰符(Event Modifiers),让我们可以通过后缀名的方式,在模板层面直接处理这些常见的 DOM 事件细节。修饰符由点号
. 表示,可以连用。以下是常用的事件修饰符及其作用:
1. .stop
作用:调用
场景:点击子元素时,不希望触发父元素的点击事件。
event.stopPropagation(),阻止事件冒泡。场景:点击子元素时,不希望触发父元素的点击事件。
html
预览
1<!-- 点击 inner 只会触发 handleInner,不会触发 handleOuter -->
2<div @click="handleOuter">
3 <button @click.stop="handleInner">点击我(不冒泡)</button>
4</div>
2. .prevent
作用:调用
场景:表单提交时不刷新页面,或阻止链接跳转。
event.preventDefault(),阻止默认行为。场景:表单提交时不刷新页面,或阻止链接跳转。
html
预览
1<!-- 提交表单时不再刷新页面 -->
2<form @submit.prevent="handleSubmit">
3 <button type="submit">提交</button>
4</form>
5
6<!-- 阻止链接跳转 -->
7<a href="/home" @click.prevent="goHomeWithoutReload">首页</a>
3. .capture
作用:使用捕获模式添加事件监听器。
场景:需要在事件到达目标元素之前就先处理(即从外向内触发)。
场景:需要在事件到达目标元素之前就先处理(即从外向内触发)。
html
预览
1<!-- 外层 div 会在捕获阶段先于内层 button 触发 -->
2<div @click.capture="handleCapture">
3 <button @click="handleBtn">按钮</button>
4</div>
4. .self
作用:只有当事件是从监听器绑定的元素本身触发时才触发回调,不包括子元素。
场景:点击模态框背景关闭模态框,但点击模态框内容时不关闭。
场景:点击模态框背景关闭模态框,但点击模态框内容时不关闭。
html
预览
1<!-- 只有直接点击 div 本身才触发,点击内部的 p 标签不会触发 -->
2<div @click.self="closeModal">
3 <p>这里是内容,点击我不会关闭模态框</p>
4</div>
5. .once
作用:只触发一次回调。
场景:初始化操作、一次性弹窗提示等。
场景:初始化操作、一次性弹窗提示等。
html
预览
1<!-- 这个点击事件只会生效一次 -->
2<button @click.once="showWelcome">只显示一次的欢迎</button>
6. .passive
作用:添加
场景:移动端滚动事件优化。
{ passive: true } 监听器,主要用于优化滚动性能(告诉浏览器你不会调用 preventDefault)。场景:移动端滚动事件优化。
html
预览
1<div @scroll.passive="onScroll">...</div>
7. 按键修饰符(Key Modifiers)
除了上述通用修饰符,
v-on 在监听键盘事件时还支持按键修饰符,让你无需判断 event.keyCode。- 普通按键:
.enter,.tab,.delete,.esc,.space,.up,.down等。 - 系统修饰键:
.ctrl,.alt,.shift,.meta。
html
预览
1<!-- 只有在按下 Enter 键时才触发 submit -->
2<input @keyup.enter="submit" />
3
4<!-- 只有在按下 Ctrl + S 时才触发 save -->
5<input @keyup.ctrl.s="save" />
8. 鼠标按钮修饰符
Vue 2.5.0+ 还引入了鼠标按钮修饰符:
.left.right.middle
html
预览
1<!-- 仅在右键点击时触发 -->
2<div @contextmenu.right.prevent="showContextMenu">右键菜单</div>
四、修饰符的链式调用
修饰符的一个强大之处在于它们可以链式调用。Vue 会按照顺序处理它们。
例如,如果你想阻止点击事件冒泡,并且只在按下 Enter 键时触发,你可以这样写:
html
预览
1<!-- 同时使用 stop 和 prevent -->
2<a @click.stop.prevent="doThat"></a>
3
4<!-- 键盘事件组合:只有 Enter 键且阻止默认行为 -->
5<form @keydown.enter.prevent="submitForm"></form>
注意顺序:大多数情况下顺序不影响结果,但在某些特定逻辑下(如
.self 和 .once 的组合),理解执行顺序很重要。通常建议按照逻辑直觉书写。五、总结
v-on(或其简写 @)是 Vue 连接用户交互与应用逻辑的桥梁。通过合理使用事件修饰符,我们可以:- 保持代码整洁:将 DOM 操作细节从 JavaScript 方法中剥离,留在模板层。
- 提高开发效率:无需编写冗长的
if (e.keyCode === 13)或e.preventDefault()。 - 增强可读性:一眼就能看出事件触发的条件和行为。
掌握这些技巧,你的 Vue 代码将更加优雅、高效且易于维护。下次编写事件监听时,不妨试试这些修饰符,体验一下 Vue 带来的declarative(声明式)编程魅力!