当前位置: 首页 > news >正文

Vue中的事件修饰符

一、概述

在 Vue 中,这些带 . 的符号叫做 事件修饰符,作用是简化事件处理中常见的操作(比如阻止冒泡、阻止默认行为),不用再手动写复杂的原生 JS 代码(如 e.stopPropagation())。下面结合 Vue 实例,讲清楚每个修饰符的作用和场景:

修饰符,主要分为三种类型:

  • 事件修饰符(.stop .prevent等):处理事件传递和行为;
  • 表单修饰符(.tirm ,number等):处理输入数据格式化;
  • 鼠标修饰符(.left .right等):限制鼠标触发方式;

二、事件修饰符

1. .stop:阻止事件冒泡

什么是 “事件冒泡”?

事件会从触发的 “子元素” 向上传递到 “父元素”,就像水泡从水底冒到水面。比如点击子按钮,父盒子的点击事件也会跟着触发。

.stop 的作用:

掐断这个 “冒泡” 过程,只让当前元素的事件执行,父元素的同名事件不触发。

Vue 示例:
<template><!-- 父盒子:有点击事件 --><div class="parent" @click="parentClick">父盒子<!-- 子按钮:加 .stop 阻止冒泡 --><button @click.stop="childClick">点击我(不触发父事件)</button></div>
</template><script>
export default {methods: {parentClick() {console.log("父盒子被点击了");},childClick() {console.log("子按钮被点击了");}}
};
</script><style>
.parent {padding: 20px;background: #eee;
}
</style>
效果:

点击子按钮时,只打印 子按钮被点击了(父事件不触发);如果去掉 .stop,会同时打印两个日志。

2. .prevent:阻止默认事件

什么是 “默认事件”?

浏览器自带的、不需要手动写的事件行为,比如:

  • 点击 <a> 标签会跳转页面
  • 表单 <button type="submit"> 点击会提交表单并刷新页面
  • 按回车键会触发表单提交
.prevent 的作用:

取消这些浏览器自带的默认行为,让你自己控制事件逻辑。

Vue 示例 1:阻止链接跳转
<template><!-- 加 .prevent 后,点击链接不会跳转 --><a href="https://www.baidu.com" @click.prevent="handleLinkClick">点我不会跳转到百度</a>
</template><script>
export default {methods: {handleLinkClick() {console.log("链接被点击了,但没跳转");// 你可以在这里写自己的逻辑,比如打开弹窗}}
};
</script>
Vue 示例 2:阻止表单默认提交
<template><!-- 表单提交时,阻止默认刷新页面 --><form @submit.prevent="handleFormSubmit"><input type="text" v-model="username" placeholder="输入用户名"><button type="submit">提交表单</button></form>
</template><script>
export default {data() {return { username: "" };},methods: {handleFormSubmit() {console.log("表单提交了,用户名:", this.username);// 这里可以写 AJAX 请求提交数据,页面不会刷新}}
};
</script>

3. .capture:事件捕获模式

先搞懂 “捕获” vs “冒泡”:

事件触发有两个阶段:

  • 捕获阶段:事件从 “最外层父元素” 向下传递到 “触发的子元素”(从上到下)
  • 冒泡阶段:事件从 “触发的子元素” 向上传递到 “最外层父元素”(从下到上)

默认情况下,Vue 的 @click 监听的是 “冒泡阶段” 的事件;加了 .capture 后,会监听 “捕获阶段” 的事件。

.capture 的作用:

让父元素 “主动拦截” 子元素的事件(在捕获阶段就触发),而不是等事件冒泡上来才触发。

Vue 示例:
<template><!-- 父盒子:加 .capture 监听捕获阶段 --><div class="parent" @click.capture="parentCapture">父盒子(捕获模式)<!-- 子盒子:正常监听冒泡阶段 --><div class="child" @click="childBubble">子盒子(冒泡模式)</div></div>
</template><script>
export default {methods: {parentCapture() {console.log("父盒子捕获阶段触发");},childBubble() {console.log("子盒子冒泡阶段触发");}}
};
</script><style>
.parent { padding: 20px; background: #eee; }
.child { padding: 10px; background: #ccc; }
</style>
效果:

点击子盒子时,日志顺序是:父盒子捕获阶段触发 → 子盒子冒泡阶段触发(因为捕获阶段先执行,再到冒泡阶段);如果父盒子去掉 .capture,顺序会反过来。

4. .self:只响应自身触发的事件

作用:

事件只有直接点击当前元素本身时才执行;如果是 “子元素冒泡上来的事件” 或 “父元素捕获下来的事件”,都不执行。

简单说:“谁触发的归谁,不是我触发的我不处理”。

Vue 示例:
<template><!-- 父盒子:加 .self,只处理自己被点击的情况 --><div class="parent" @click.self="parentClick">父盒子(只响应自身点击)<!-- 子按钮:点击时事件会冒泡到父盒子,但父盒子 .self 不处理 --><button @click="childClick">点击子按钮</button></div>
</template><script>
export default {methods: {parentClick() {console.log("父盒子自己被点击了");},childClick() {console.log("子按钮被点击了");}}
};
</script>
效果:
  • 点击 “父盒子的空白区域”:打印 父盒子自己被点击了(自身触发)
  • 点击 “子按钮”:只打印 子按钮被点击了(父盒子不处理冒泡过来的事件)

5. .once:事件只执行一次

作用:

事件绑定后,只能触发一次,触发后就自动解绑(相当于 “一次性事件”)。

常见场景:按钮点击一次后失效(如 “提交订单”“发送验证码” 按钮,防止重复点击)。

Vue 示例:
<template><!-- 按钮加 .once,点击一次后就失效 --><button @click.once="handleOnceClick">点击我(只能点一次)</button>
</template><script>
export default {methods: {handleOnceClick() {console.log("按钮被点击了,下次点没用了");// 比如这里发验证码请求,只发一次}}
};
</script>
效果:

第一次点击按钮:打印日志;第二次及以后点击:没任何反应(事件已解绑)。

总结:事件修饰符的核心价值

  • 不用手动写原生 JS 代码(如 e.stopPropagation() e.preventDefault()),代码更简洁;
  • 语义化更强,一看 .stop 就知道是阻止冒泡,不用猜逻辑;
  • 支持链式使用(比如 @click.stop.prevent,先阻止冒泡再阻止默认事件)。

比如一个 “点击不跳转的链接,且只点一次”:

<a href="https://baidu.com" @click.stop.prevent.once="handleClick">点我:不跳转、不冒泡、只一次
</a>

once拓展:

.once 是 “单次绑定” 的事件修饰符,它的 “只执行一次” 是针对「当前页面加载周期内的事件绑定」—— 刷新页面后,页面会重新初始化 Vue 实例、重新绑定事件,.once 也会跟着 “重置”,再次变成 “可执行一次” 的状态。

举个实际例子理解:

比如你写了一个带 .once 的按钮:

<template><button @click.once="sayHi">点击我(只生效一次)</button>
</template>
<script>
export default {methods: {sayHi() {alert("你好!这是第一次点击~");}}
};
</script>
操作流程与效果:
  1. 第一次打开页面

    • 点击按钮 → 弹出 “你好!这是第一次点击~”(.once 生效,触发后事件解绑);
    • 再点击按钮 → 没任何反应(事件已解绑)。
  2. 刷新页面后

    • Vue 重新创建实例,按钮的 @click.once 重新绑定;
    • 再次点击按钮 → 又会弹出 “你好!这是第一次点击~”(.once 重新生效);
    • 再点又没反应(再次解绑)。

关键原因:

.once 的 “单次限制” 是 临时的,只存在于「当前页面的内存中」—— 刷新页面会清空当前页面的内存状态,Vue 会从头开始解析模板、绑定事件,相当于 “一切重来”,所以 .once 会恢复初始的 “可执行一次” 状态。

如果想实现 “跨刷新也只执行一次”(比如 “用户终身只能点击一次某个按钮”),.once 就不够了,需要借助 持久化存储(如 localStorage)记录状态,比如:

<template><button @click="sayHi" :disabled="hasClicked">{{ hasClicked ? "已点击过" : "点击我(终身一次)" }}</button>
</template>
<script>
export default {data() {// 从 localStorage 读取状态:是否已经点击过return { hasClicked: localStorage.getItem("clicked") === "true" };},methods: {sayHi() {if (this.hasClicked) return;alert("你好!这是你终身第一次点击~");// 记录状态到 localStorage,跨刷新不丢失localStorage.setItem("clicked", "true");this.hasClicked = true;}}
};
</script>

这种方式下,即使刷新页面,也会记住 “已经点击过” 的状态,按钮不会再生效。

三、表单输入修饰符(v-model 专用)

这类修饰符配合 v-model 使用,用于快速处理表单输入的常见需求(如格式化、过滤输入等)。

1. .trim

作用:自动过滤输入框首尾的空白字符(空格、换行等)。
场景:避免用户不小心输入的前后空格影响数据(比如用户名、手机号)。

<template><input v-model.trim="username" placeholder="输入用户名(自动去首尾空格)"><p>处理后的值:"{{ username }}"</p>
</template><script>
export default {data() {return { username: "" };}
};
</script>

效果:输入 张三 时,username 会自动变成 张三(去掉首尾空格)。

2. .number

作用:将输入的字符串自动转为数字类型(如果能转的话)。
场景:表单中需要数字的场景(如年龄、数量),避免后续处理时手动转换类型。

<template><input v-model.number="age" type="text" placeholder="输入数字(自动转number类型)"><p>类型:{{ typeof age }}</p> <!-- 输入"18"时,显示"number" -->
</template><script>
export default {data() {return { age: null };}
};
</script>

注意:如果输入的是无法转为数字的内容(如字母),会保留字符串类型。

3. .lazy

作用:让 v-model 不再实时同步输入(默认是输入时实时更新),而是在输入框失去焦点按下回车后才同步数据。
场景:减少频繁的数据更新(比如长文本输入,避免每输入一个字就触发一次更新)。

<template><input v-model.lazy="content" placeholder="输入内容(失去焦点后更新)"><p>当前值:{{ content }}</p> <!-- 输入时不更新,失去焦点才更新 -->
</template><script>
export default {data() {return { content: "" };}
};
</script>

四、鼠标按钮修饰符

这类修饰符用于限制鼠标事件只能由特定按钮触发(主要针对 click 类事件)。

1. .left

作用:只有点击鼠标左键时,事件才会触发。

2. .right

作用:只有点击鼠标右键时,事件才会触发。

3. .middle

作用:只有点击鼠标中键(滚轮键)时,事件才会触发。

示例

<template><div><button @click.right="showMsg('右键')">右键点击我</button><button @click.left="showMsg('左键')">左键点击我</button><button @click.middle="showMsg('中键')">中键点击我</button></div>
</template><script>
export default {methods: {showMsg(type) {alert(`你点击了${type}`);}}
};
</script>

效果:右键点击第一个按钮才会触发弹窗,左键点击第二个才会触发,以此类推。

总结

Vue 的修饰符本质是 “语法糖”,简化了常见操作:

  • 事件修饰符(.stop .prevent 等):处理事件传递和行为;
  • 表单修饰符(.trim .number 等):处理输入数据格式化;
  • 鼠标修饰符(.left .right 等):限制鼠标触发方式。

合理使用能让代码更简洁,减少重复逻辑。

http://www.dtcms.com/a/357052.html

相关文章:

  • uni-app 常用钩子函数:从场景到实战,掌握开发核心
  • MySQL 深分页:性能优化
  • 每周AI看 | 微软开源VibeVoice-1.5B、OpenAI历史性交棒、网易云商出席AICon全球人工智能开发与应用大会
  • MCP Java Sdk 添加key认证
  • CMake构建学习笔记22-libxml2库的构建
  • 【链表 - LeetCode】146. LRU 缓存
  • Prometheus+Grafana入门教程:从零搭建云原生服务器监控系统
  • 如何管理跨境电商多语种素材?数字资产本地化指南
  • nacos单机部署并开启鉴权
  • #医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(五)
  • 机器学习 - Kaggle项目实践(5)Quora Question Pairs 文本相似
  • OpenCV轮廓近似与Python命令行参数解析
  • 玳瑁的嵌入式日记D29-0829(进程间通信)
  • ZooKeeper 安装配置
  • idea2025.2中maven编译中文乱码
  • Altium Designer 22使用笔记(10)---PCB铺铜相关操作
  • c++ const 关键字
  • 聊聊Prompt Engineering (提示词工程)
  • 【工具类】得到多个数组中的相同元素
  • 考研数据结构Part3——二叉树知识点总结
  • Vue学习Ⅳ
  • 二手车估值查询-二手车估值api接口
  • el-table实现双击编辑-el-select选择框+输入框限制非负两位小数
  • HunyuanVideo-Foley视频音效生成模型介绍与部署
  • 非标设计 机架模板 misumi 设计组合案例
  • 浏览器自动化工具怎么选?MCP 控制浏览器 vs Selenium 深度对比
  • 预测模型及超参数:3.集成学习:[1]LightGBM
  • LangChain实战(三):深入理解Model I/O - Prompts模板
  • 顶会顶刊图像分类的云服务器训练方法
  • 闭包与内存泄漏:深度解析与应对策略