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

Vue 3 事件处理

1. 基本概念

在 Vue 3 中,事件处理是组件交互的核心部分。Vue 使用 v-on 指令(简写为 @)来监听 DOM 事件,并在触发时执行相应的 JavaScript 代码。

2. 基本用法

2.1 内联事件处理器

<template><button @click="count++">点击次数: {{ count }}</button>
</template><script setup>
import { ref } from 'vue'const count = ref(0)
</script>

2.2 方法事件处理器

<template><button @click="handleClick">点击我</button>
</template><script setup>
const handleClick = () => {console.log('按钮被点击了!')alert('Hello Vue 3!')
}
</script>

3. 事件修饰符

Vue 提供了一些事件修饰符来处理常见的 DOM 事件细节。

3.1 常用修饰符

<template><!-- 阻止默认行为 --><form @submit.prevent="onSubmit"><button type="submit">提交</button></form><!-- 阻止事件冒泡 --><div @click="outerClick"><div @click.stop="innerClick">内部区域</div></div><!-- 事件只触发一次 --><button @click.once="doOnce">只能点击一次</button><!-- 按键修饰符 --><input @keyup.enter="submitForm" placeholder="按回车提交" /><input @keyup.ctrl.enter="submitForm" placeholder="按Ctrl+回车提交" /><!-- 鼠标按键修饰符 --><div @click.right="rightClick">右键点击我</div><div @click.middle="middleClick">中键点击我</div>
</template>

3.2 按键修饰符

<template><!-- 特定按键 --><input @keyup.enter="submit" /><input @keyup.tab="nextField" /><input @keyup.delete="deleteItem" /><!-- 系统按键修饰符 --><input @keyup.ctrl.enter="ctrlEnter" /><input @keyup.shift.space="shiftSpace" /><!-- 精确修饰符 --><button @click.ctrl.exact="ctrlClick">只有 Ctrl 被按下时才触发</button>
</template>

4. 事件参数传递

4.1 传递原生事件

<template><!-- 自动传递事件对象 --><button @click="handleClick">点击</button><!-- 手动传递事件对象 --><button @click="handleClick($event)">点击</button>
</template><script setup>
const handleClick = (event) => {console.log('事件对象:', event)console.log('目标元素:', event.target)
}
</script>

4.2 传递自定义参数

<template><button @click="handleClick('参数1', '参数2', $event)">点击</button>
</template><script setup>
const handleClick = (param1, param2, event) => {console.log('参数1:', param1)console.log('参数2:', param2)console.log('事件对象:', event)
}
</script>

5. 组件事件

5.1 子组件触发事件

<!-- ChildComponent.vue -->
<template><button @click="emitClick">点击触发事件</button>
</template><script setup>
import { defineEmits } from 'vue'// 定义可触发的事件
const emit = defineEmits(['click', 'custom-event'])const emitClick = () => {// 触发 click 事件emit('click')// 触发带参数的事件emit('custom-event', '参数1', '参数2')
}
</script>

5.2 父组件监听事件

<!-- ParentComponent.vue -->
<template><ChildComponent @click="handleChildClick"@custom-event="handleCustomEvent"/>
</template><script setup>
import ChildComponent from './ChildComponent.vue'const handleChildClick = () => {console.log('子组件点击事件被触发')
}const handleCustomEvent = (param1, param2) => {console.log('自定义事件:', param1, param2)
}
</script>

6. 高级用法

6.1 多个事件处理器

<template><button @click="firstHandler(); secondHandler()">点击触发多个方法</button>
</template><script setup>
const firstHandler = () => {console.log('第一个处理器')
}const secondHandler = () => {console.log('第二个处理器')
}
</script>

6.2 动态事件名

<template><button @[eventName]="handleEvent">动态事件</button>
</template><script setup>
import { ref } from 'vue'const eventName = ref('click')const handleEvent = () => {console.log('动态事件被触发')
}// 可以动态改变监听的事件
setTimeout(() => {eventName.value = 'mouseenter'
}, 2000)
</script>

6.3 事件总线(Event Bus)替代方案

// eventBus.js
import mitt from 'mitt'export const emitter = mitt()// ComponentA.vue
import { emitter } from './eventBus'
emitter.emit('event-name', data)// ComponentB.vue
import { emitter } from './eventBus'
import { onMounted, onUnmounted } from 'vue'onMounted(() => {emitter.on('event-name', handleEvent)
})onUnmounted(() => {emitter.off('event-name', handleEvent)
})

7. 最佳实践

  1. 命名规范:使用 kebab-case 命名自定义事件

  2. 参数传递:传递有意义的参数,避免过多依赖事件对象

  3. 解耦:组件事件应尽量保持组件间的解耦

  4. 清理:在组件卸载时清理事件监听器

  5. 类型安全:使用 TypeScript 定义事件类型

<!-- 使用 TypeScript 的类型定义 -->
<script setup lang="ts">
interface Emits {(e: 'update:modelValue', value: string): void(e: 'submit', payload: { id: number, data: any }): void
}const emit = defineEmits<Emits>()
</script>

8. Composition API 中的事件处理

<template><div @mousemove="handleMouseMove"@mouseleave="handleMouseLeave">鼠标位置: {{ x }}, {{ y }}</div>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue'const x = ref(0)
const y = ref(0)const handleMouseMove = (event) => {x.value = event.clientXy.value = event.clientY
}const handleMouseLeave = () => {x.value = 0y.value = 0
}// 手动添加事件监听器
onMounted(() => {window.addEventListener('resize', handleResize)
})onUnmounted(() => {window.removeEventListener('resize', handleResize)
})const handleResize = () => {console.log('窗口大小改变了')
}
</script>

Vue 3 的事件处理系统保持了 Vue 2 的简洁性,同时在 Composition API 中提供了更灵活的方式来管理和组织事件逻辑。

 

http://www.jsqmd.com/news/366057/

相关文章:

  • 完整教程:YOLOv4 核心笔记:兼顾速度与精度的全方位优化
  • 2026年深圳钢琴搬运公司评测推荐榜单:告别搬运难题,专业服务安心之选 - 十大品牌推荐
  • python中logger.info 打印多个变量值
  • 2026年医疗器械注册公司推荐|五家值得信赖的公司提供中美欧多市场注册解决方案 - 速递信息
  • 开源无人机实战指南:从DIY组装到自主飞行控制
  • 护航打破申学迷茫,南京留学中介排名TOP10全程助力 - 博客湾
  • 2026年动物实验机构综合实力盘点:五家领先服务商各有千秋 - 速递信息
  • SQL中,防止除0错误
  • 如何选择医疗器械注册机构?2026年五大优质机构对比及选择指南 - 速递信息
  • 2026年深圳东方双狮手表维修推荐榜单:非官方维修点甄别与全国服务网点评测 - 十大品牌推荐
  • 分享2026年杭州西湖龙井茶绿色认证茶叶门店的选购经验 - mypinpai
  • 剖析无锡企业外贸推广,好用的企业海外贸易推广服务有哪些 - 工业品牌热点
  • 北京留学中介TOP10实锤!找准机构,留学上岸不内耗 - 博客湾
  • 双曲面搅拌机好用的推荐供应商有哪些,南京蓝恒在列 - 工业品网
  • 2026年高品质荞麦食品厂家分析,荞麦食品品牌厂家怎么选择 - 工业推荐榜
  • 每次都需要安装一次bootloader interface 驱动?
  • 留学申请决胜点:北京留学机构用文书打开名校之门 - 博客湾
  • 信誉与实力兼备:五家口碑好的动物实验机构权威指南 - 速递信息
  • 2026年降AIGC保留原文有多难?用对工具其实很简单
  • 昆明本地生活团购代运营公司测评 头部梯队实力解析 - 野榜数据排行
  • STM32_CubeMx安装
  • 2026宝宝起名机构推荐榜:传统与现代的平衡术,这4家机构最懂父母需求 - 博客万
  • 2026年NMN哪个牌子好?全球抗衰医学白皮书:十大红榜品牌与选购避坑准则 - 速递信息
  • [LangGraph] 超步
  • 买米克朗机床去哪个网站?2026最新采购路径解析 - 品牌推荐大师1
  • 动物实验机构选择指南:五家资质齐全的权威服务商推荐 - 速递信息
  • 2026年新一代AI语音客服机器人厂商推荐及解决方案解析 - 品牌2025
  • 基于Spring Boot的少儿编程管理系统设计与实现(毕业论文)
  • 2026全国有机肥哪家强?从技术到服务的全方位对比 适配多场景种植需求与差异化选型参考 - 深度智识库
  • 2026年靠谱的纳米砂磨机,卧式砂磨机厂家实力优选榜 - 品牌鉴赏师