Vue 3 setup中绑定原生DOM事件推荐优先使用模板中@语法(如@click="handler"),需访问原生事件对象时直接在处理器中接收参数;手动通过ref+addEventListener适用于动态控制场景,须配合onMounted和onBeforeUnmount确保正确挂载与清理。

在 Vue 3 的 setup 中绑定原生 DOM 事件,核心是通过模板引用(ref)获取 DOM 元素,再用 addEventListener 或直接在模板中使用 v-on(即 @)语法。推荐优先使用声明式写法,仅在需要手动控制时才操作 DOM。
用 ref 获取元素后手动绑定事件
适用于需要动态添加/移除监听器、或访问原生事件细节(如 event.target、event.preventDefault())的场景。
- 在
setup中定义一个响应式引用:const myInput = ref(null) - 在模板中通过
ref="myInput"绑定该引用 - 使用
onMounted确保 DOM 已挂载,再调用myInput.value.addEventListener(...) - 记得在
onBeforeUnmount中清理监听器,避免内存泄漏
直接在模板中用 v-on 绑定(最常用)
绝大多数情况无需手动操作 DOM,Vue 会自动将事件委托到对应元素上,写法简洁且响应式友好。
- 在模板中写:
- 在
setup中定义函数并返回:const handleClick = () => { console.log('触发了') } - 支持所有原生事件:@input、@focus、@keydown、@scroll 等,也支持修饰符如
@click.stop、@keyup.enter
访问原生事件对象的小技巧
当需要原生事件对象(比如阻止默认行为、获取键盘码),直接在事件处理器中接收参数即可。
-
@submit="handleSubmit"→const handleSubmit = (e) => { e.preventDefault(); ... } - 若同时需要自定义参数,用箭头函数包裹:
@click="(e) => handleClick(id, e)" - 注意:不要写成
@click="handleClick(id, $event)",这在 setup 语法糖(<script setup></script>)中不推荐,易出错
处理动态渲染元素的事件绑定
比如列表中每个项都有删除按钮,需区分点击的是哪一个。不建议给每个元素都加 ref,而是利用事件冒泡 + event.target 或数据驱动逻辑。
- 给父容器绑定事件,用
event.target.dataset.id或event.target.closest('[data-id]')定位 - 更推荐方式:在模板中直接传参,如
v-for="(item, i) in list" :key="i"> - 确保 key 值稳定,避免因 DOM 复用导致事件绑定错乱










