Vue事件捕获方式(capture修饰符)
作者:WZMeiei
这篇文章主要介绍了Vue事件捕获方式(capture修饰符),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
一、先理解 DOM 事件的 “传播三阶段”
当你点击一个按钮,浏览器处理事件分 3 步(像 “快递送货”,有固定流程):
阶段 | 行为描述 | 类比场景 |
---|---|---|
捕获阶段 | 事件从 document 出发,由外到内找目标(父元素 → 子元素) | 快递从省会 → 市 → 区 → 小区 |
目标阶段 | 找到目标元素(比如按钮自己),执行事件 | 快递送到你家门口 |
冒泡阶段 | 事件从目标元素出发,由内到外向上传播(子元素 → 父元素 → 更外层父元素) | 你取到快递后,消息从家 → 小区 → 区 → 市 |
二、默认情况:事件在 “冒泡阶段” 触发
Vue 里写 @click="xxx"
,默认监听的是 冒泡阶段 的事件。
示例(无 capture
修饰符):
<div class="parent" @click="parentClick"> 父元素 <button class="child" @click="childClick">子元素(按钮)</button> </div>
methods: { parentClick() { console.log('父元素(冒泡阶段)触发'); }, childClick() { console.log('子元素(冒泡阶段)触发'); } }
执行顺序(点击按钮):
- 进入捕获阶段:父元素没加
capture
,所以捕获阶段不触发parentClick
。 - 进入目标阶段:触发按钮自己的点击(但按钮逻辑在冒泡阶段,所以这一步不算 “触发方法”)。
- 进入冒泡阶段:先触发子元素的
childClick
→ 再触发父元素的parentClick
。
控制台输出:
子元素(冒泡阶段)触发
父元素(冒泡阶段)触发
三、加 capture 修饰符:强制 “捕获阶段” 触发
给父元素加 @click.capture
,让父元素的事件 在捕获阶段就触发,改变执行顺序。
示例(加 capture
修饰符):
<div class="parent" @click.capture="parentCapture"> 父元素 <button class="child" @click="childBubble">子元素(按钮)</button> </div>
methods: { parentCapture() { console.log('父元素(捕获阶段)触发'); }, childBubble() { console.log('子元素(冒泡阶段)触发'); } }
执行顺序(点击按钮):
- 进入捕获阶段:父元素加了
capture
,所以先触发parentCapture
。 - 进入目标阶段:触发按钮自己的点击(不影响方法顺序)。
- 进入冒泡阶段:触发子元素的
childBubble
。
控制台输出:
父元素(捕获阶段)触发
子元素(冒泡阶段)触发
四、核心区别:“捕获阶段” vs “冒泡阶段”
场景 | 触发顺序(点击子元素) | 关键逻辑 |
---|---|---|
无 capture | 子(冒泡) → 父(冒泡) | 默认是冒泡阶段 |
父加 capture | 父(捕获) → 子(冒泡) | 父元素 “插队” 到捕获阶段执行 |
五、再举个极端例子(多层嵌套)
<div class="grandpa" @click.capture="grandpaCapture"> 爷爷元素 <div class="parent" @click.capture="parentCapture"> 爸爸元素 <button class="child" @click="childBubble">孙子按钮</button> </div> </div>
methods: { grandpaCapture() { console.log('爷爷(捕获)触发'); }, parentCapture() { console.log('爸爸(捕获)触发'); }, childBubble() { console.log('孙子(冒泡)触发'); } }
执行顺序(点击孙子按钮):
- 捕获阶段:爷爷(最外层)→ 爸爸(中间层)→ 孙子(目标)
→ 先触发grandpaCapture
→ 再触发parentCapture
- 目标阶段:触发孙子按钮(无
capture
,不影响) - 冒泡阶段:触发
childBubble
控制台输出:
爷爷(捕获)触发
爸爸(捕获)触发
孙子(冒泡)触发
六、一句话总结 capture
capture
修饰符的作用是:让事件在 “捕获阶段” 就触发,改变默认的 “冒泡阶段触发” 顺序,实现 父元素优先响应(不管子元素有没有触发,父元素先执行自己的逻辑)。
记住一个关键点:
- 默认是 “子 → 父”(冒泡)
- 加
capture
是 “父 → 子”(捕获)
@click.capture
,相当于是是改变事件传播顺序的 “插队符”
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。