Vue 3.6 rc.13 把 Vapor 事件委托改为 opt-in:祖先调用 stopPropagation() 不再让子元素 handler 失效
仓库:
变更概览
3.6.0-rc.13(2026-10-23)中,compiler-vapor 把事件委托改成了显式开启(PR #15127,commit 810a1ef),列为 BREAKING CHANGE。
为了让 Vapor Mode 与标准 Vue、原生 DOM 的事件行为对齐,DOM 事件监听器现在默认直接绑在元素上。以前受支持的事件会被自动委托到 document,这会带来和 VDOM Mode 的行为差异——最典型的一种:祖先调用 stopPropagation() 后,子元素的 handler 不执行。
旧行为:委托到 document
按早前 rc.1 发布说明的描述,Vapor 会把符合条件的事件委托到 document:每个元素自己保存 handler,由 document 上的单个监听器沿事件路径查找并调用匹配的 handler。
问题出在事件根本到不了 document 的情况——只要路径上任意一层祖先调用了 stopPropagation(),事件就停在半路,被委托的 handler 不会运行。
实际表现就是:某个第三方组件库在自己的容器节点上停了冒泡,容器里的 Vapor 按钮点了没反应。这不是按钮的 handler 写错了,而是事件没有走到 document。
新用法:用 .delegate 显式开启
document 级委托现在被当作一种显式优化。对受支持的静态事件,用 Vapor 专属的 .delegate 修饰符开启:
同时,compilerOptions.eventDelegation 选项已被移除。已有配置里的这一项要删掉;确实需要委托的监听器,逐个补上 .delegate。
这些写法不走委托
下面几种形式会绕过委托,直接把监听器绑到元素上:
也就是说,动态事件名 @[event]、对象形式的 v-bind 和 v-on 都不参与委托,行为与默认的直接绑定一致。
迁移
- 删除配置里的
compilerOptions.eventDelegation。 - 对确实需要 document 级委托的静态事件,逐个加
.delegate;其余保持默认的直接绑定,语义与 VDOM、原生 DOM 一致。 - 与 VDOM 混用时留意两侧的事件绑定差异,不要再依赖「祖先停冒泡、子元素仍能收到事件」这种 Vapor 独有行为。
版本状态
Vue 3.6 仍在 RC 阶段,RC.15 发布于 2026-11-12。当前最新稳定补丁版本是 v3.5.45,生产环境仍用 3.5.x。