给组件绑定原生事件

本文探讨了在前端开发中如何区分并正确使用自定义事件与原生事件。介绍了在组件内绑定自定义事件的方法及触发机制,并解释了如何通过添加native关键字监听原生事件。

先写一个事件绑定

这段代码点击Child是没有作用的

这是因为当我给一个组件绑定一个事件的时候,<child @click="handleClick"></child>,这个实际上绑定的是一个自定义的事件

当你鼠标点击的时候,触发的并不是这个click事件

当我点击的时候,就能够触发childclick事件

这是因为当我在div里面绑定事件<div @click="handleChildClick">Child</div>是原生的事件,在child里面绑定的事件

<child @click="handleClick"></child>是自定义事件

那么我现在想要触发这个自定义事件,需要在通过this.$emit来触发自定义事件

就有click出来了
执行逻辑是:首先当你点击了div元素的时候,div会监听<div @click="handleChildClick">Child</div>到自身被点击了,然后向外触发this.$emit('click');了一个自定义事件,然后在组件中<child @click="handleClick"></child>监听了这个自定义事件,那么这个自定义事件就会被执行

当然这样写太过麻烦:

我就想在child上监听原生事件,可不可以呢?可以的

@click.native="handleClick"在自定义事件后面添加一个native就会变成监听原生事件了

### Vue2 和 Vue3 中为自定义组件绑定原生事件的触发问题及解决方案 #### 一、Vue2 中的原生事件绑定行为 在 Vue2 中,当尝试在一个自定义组件绑定原生 DOM 事件时,这些事件并不会自动传播到该组件的根元素。这是因为 Vue 默认认为这些事件是针对整个组件的行为而非其内部的具体 DOM 节点[^1]。 例如,假设有一个按钮组件 `<MyButton>`,在其外部绑定了一个点击事件: ```html <MyButton @click="handleClick"></MyButton> ``` 如果 `<MyButton>` 的模板是一个普通的 `<button>` 元素,则上述代码中的 `@click` 并不会生效,除非手动将其映射到根节点。 解决方法之一是在子组件中显式地使用 `$listeners` 或者直接绑定事件到根元素。例如: ```javascript // MyButton.vue <template> <button v-on="$listeners">点击我</button> </template> <script> export default { name: 'MyButton' }; </script> ``` 这样就可以让父级绑定的所有事件(包括原生事件)都传递到子组件的根元素上[^4]。 --- #### 二、Vue3 中的变化及其影响 Vue3 对事件系统的改进使得这种问题得到了更好的处理。在 Vue3 中,`.native` 修饰符已被移除,取而代之的是更清晰的机制——即通过 `v-on` 自动将事件绑定组件的根节点。这意味着,在大多数情况下不再需要额外的操作即可完成原生事件绑定。 然而需要注意的一点是,如果希望阻止某些特定事件冒泡或修改默认行为,可能仍需在子组件中进行一些配置。比如: ```javascript // MyButton.vue (Vue3) <template> <button @click.stop="internalHandler">点击我</button> </template> <script> import { defineComponent } from 'vue'; export default defineComponent({ name: 'MyButton', setup() { const internalHandler = () => console.log('Internal handler triggered'); return { internalHandler }; } }); </script> ``` 在此示例中,尽管父组件仍然可以监听 `@click`,但由于 `.stop` 阻断了冒泡链路,因此仅限于当前层面上捕获事件[^3]。 另外值得注意的是,对于非根级别的嵌套结构来说,依然有必要明确指出哪些部分应该接收相应的交互信号[^2]。 --- #### 三、总结对比表 | 功能/版本 | Vue2 | Vue3 | |-----------|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------| | 默认行为 | 不会自动转发到根元素 | 自动应用到顶层 HTML 标记 | | 处理方式 | 使用 `$listeners` 或 `.native` 修改器 | 利用更新后的组合 API 及简化版侦听器 | | 移除特性 | 支持 `.native` | 已废弃 | --- ### 示例代码展示 以下是基于两个框架分别实现同样功能的例子: **Vue2** ```html <!-- ParentComponent.vue --> <template> <ChildComponent @click.native="onParentClick"></ChildComponent> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, methods: { onParentClick() { alert('Clicked!'); } } } </script> ``` **Vue3** ```html <!-- ParentComponent.vue --> <template> <ChildComponent @click="onParentClick"></ChildComponent> </template> <script> import { defineComponent } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default defineComponent({ components: { ChildComponent }, setup() { const onParentClick = () => alert('Clicked!'); return { onParentClick }; } }) </script> ``` 两者之间的差异在于 Vue3 更加简洁明了,同时也减少了不必要的复杂度。 ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值