网站首页 > 文章精选 正文
Vue 的事件机制主要包含以下几种类型和方式,可以分为组件内部事件、父子组件通信事件、原生 DOM 事件封装、修饰符增强等,下面详细分类介绍:
一、DOM 事件绑定(最基础的事件)
使用 v-on(或简写 @)指令绑定原生 DOM 事件。
<button @click="handleClick">点击我</button>
二、自定义事件(组件通信)
1. 子组件通过 $emit 向父组件传递事件
子组件中:
<template>
<button @click="$emit('custom-event', data)">发送事件</button>
</template>
父组件中:
<ChildComponent @custom-event="handleCustomEvent" />
2. 使用 v-model 进行双向绑定(语法糖)
Vue3 中可以绑定自定义 modelValue 和 update:modelValue:
子组件:
<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>
<script>
export default {
props: ['modelValue']
}
</script>
父组件:
<ChildComponent v-model="inputValue" />
三、事件修饰符
Vue 为事件添加了很多修饰符,用于增强行为:
- .stop:阻止事件冒泡
- .prevent:阻止默认行为
- .capture:使用事件捕获模式
- .self:只有事件是从绑定元素本身触发才触发
- .once:事件只触发一次
- .passive:使用被动监听器,适合滚动性能优化
<button @click.stop.prevent="handleClick">点我</button>
四、键盘事件修饰符
<input @keyup.enter="submit" />
还支持 .esc, .tab, .delete, .arrow-up, .space 等等。
五、事件代理(原生方式)
在 Vue 中仍然可以使用事件代理:
<ul @click="handleListClick">
<li v-for="item in list" :key="item.id" :data-id="item.id">{{ item.name }}</li>
</ul>
六、$on / $off / $emit(Vue2 中的全局事件总线)
Vue2 可以通过事件总线实现跨组件通信:
// event-bus.js
export const EventBus = new Vue();
// 发送事件
EventBus.$emit('someEvent', data);
// 接收事件
EventBus.$on('someEvent', data => { ... });
// 移除事件
EventBus.$off('someEvent');
Vue3 中已经废弃 $on / $off / $emit,推荐使用 mitt 或 emitter 等库替代。
七、Vue3 中的事件通信方式
Vue3 推荐使用以下方式进行事件通信:
- defineEmits()(组合式 API)
- mitt 第三方事件库
- provide/inject
- Pinia 或 Vuex 状态管理
- emits 选项配合 defineProps
// 子组件
const emit = defineEmits(['save']);
emit('save', payload);
八、自定义指令事件
Vue 允许你通过自定义指令实现特殊事件处理逻辑:
app.directive('click-outside', {
mounted(el, binding) {
document.addEventListener('click', (e) => {
if (!el.contains(e.target)) {
binding.value(e)
}
});
}
});
需要我帮你整理一个“Vue 事件机制脑图”或“快速参考表”吗?
猜你喜欢
- 2025-05-02 vue3跨层传递响应式数据及修改顶层数据
- 2025-05-02 前端面试必背——Vue.js中组件通信的几种方式及优缺点,附代码
- 2025-05-02 前端开发-Vite新时代构建工具(前端项目构建工具)
- 2025-05-02 Vue3 + Nest 实现权限管理系统 后端篇:如何在 NestJS 中使用 redis
- 2025-05-02 Web前端面试中,经常会被问到的Vue面试题
- 2025-05-02 Vue3中deep样式穿透的使用细节及源码解析
- 2025-05-02 基于uniapp+vue3跨端仿制chatgpt实例uniapp-chatgpt
- 2025-05-02 vue3 专用 indexedDB 封装库,基于Promise告别回调地狱
- 2025-05-02 Vue中mixin怎么理解?(vue mixins作用)
- 2025-05-02 在Vue中如何高效管理组件状态(vue 管理)
- 05-05MyBatis的三种分页方式,你学废了吗?
- 05-05如何写一个简单的分页(最简单的分页)
- 05-05详解如何使用Spring Data JPA进行数据的分页与排序
- 05-05手速太快引发分页翻车?前端竞态陷阱揭秘
- 05-05前端分页机制的具体实现(分页前端需要做什么)
- 05-05一个后勾腿动作,有效疏通血管,改善下肢发麻,促进全身燃脂
- 05-05大型调相机起动及并网研究(什么是调相机,与发电机区别)
- 05-05你们都是托:动态对比度其实是骗你的
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)