今天在项目中实现点击跳转页面的时候遇到了el-col添加@click无效的状况,查了一些相关资料,记录一下。
目录
- 简介
- 原生 HTML 元素与自定义组件
@click
的工作原理- .native 修饰符的作用
- 根元素一定是原生 HTML 元素吗?
- 总结
- 示例代码
1.简介
在 Vue.js 中,事件绑定是开发过程中非常常见的操作。@click
是一个常用的指令,用于监听点击事件。然而,在使用封装好的 UI 库组件(如 Element UI 的 el-col
)时,直接使用 @click
可能无法达到预期效果。这时,.native
修饰符就派上了用场。本文将详细解释 @click
和 .native
修饰符的工作原理。
2.原生 HTML 元素与自定义组件
- 原生 HTML 元素:指浏览器内置的 HTML 标签,如
<div>
、<button>
等。 - 自定义组件:由开发者或第三方库提供的可复用组件,如
el-col
、MyComponent
等。
3.@click
的工作原理
3.1. 绑定到原生 HTML 元素
对于原生的 HTML 元素,@click
直接绑定到该元素的点击事件上。
<!-- 绑定到原生 div 元素 -->
<div @click="handleClick">点击我</div>
3.2. 绑定到自定义组件
对于自定义组件,默认情况下,@click
监听的是组件实例上的自定义事件(即组件内部通过 $emit('click')
触发的事件)。如果组件没有定义和触发 click
事件,那么 @click
将不会有任何效果。
<!-- 自定义组件 MyComponent.vue -->
<template>
<div class="my-component">
<!-- 内部内容 -->
</div>
</template>
<script>
export default {
name: 'MyComponent'
}
</script>
<!-- 使用自定义组件 -->
<template>
<div>
<!-- 没有 .native,监听组件实例上的自定义事件 -->
<MyComponent @click="handleClick" />
</div>
</template>
<script>
import MyComponent from './MyComponent.vue'
export default {
components: {
MyComponent
},
methods: {
handleClick() {
console.log('点击了!')
}
}
}
</script>
在这个例子中,由于 MyComponent
内部没有触发 click
事件,所以点击不会触发 handleClick
。
4.native 修饰符的作用
.native
修饰符用于将事件绑定到组件的根元素(即组件模板中最外层的原生 HTML 元素)上,而不是组件实例上的自定义事件。
<!-- 使用 .native,监听组件根元素上的点击事件 -->
<MyComponent @click.native="handleClick" />
在这个例子中,@click.native
将点击事件直接绑定到 MyComponent
组件的根元素上,从而实现了预期的点击行为。
5.根元素一定是原生 HTML 元素吗?
是的,组件的根元素必须是一个原生的 HTML 元素。这是因为 Vue 的渲染机制要求每个组件最终渲染为一个 DOM 元素。即使你使用的是封装好的 UI 库组件(如 Element UI 的 el-col
),这些组件最终也会被编译成原生的 HTML 元素。
例如,el-col
组件可能最终渲染为如下结构:
<div class="el-col el-col-6" style="cursor: pointer;">
<!-- 内容 -->
</div>
因此,当你使用 .native
时,实际上是在绑定到这个最外层的 div
上的点击事件。
这里不复制源码了,大家想了解el-col
组件源码的话可以参考这个博主的文章,我上面只是举个例子。
https://www.codeleading.com/article/59365766554/
6.总结
@click
:默认监听组件实例上的自定义事件(如$emit('click')
)。如果组件没有定义和触发该事件,则不会生效。@click.native
:将点击事件绑定到组件的根元素(即最外层的原生 HTML 元素)上,确保点击事件能够正常触发。- 根元素:组件的根元素必须是原生的 HTML 元素,因为 Vue 需要将其编译为实际的 DOM 结构。
7.示例代码
为了更清楚地理解这一点,我们可以通过一个简单的例子来说明:
<!-- 自定义组件 MyComponent.vue -->
<template>
<div class="my-component">
<!-- 内部内容 -->
</div>
</template>
<script>
export default {
name: 'MyComponent'
}
</script>
<!-- 使用自定义组件 -->
<template>
<div>
<!-- 没有 .native,监听组件实例上的自定义事件 -->
<MyComponent @click="handleClick" />
<!-- 使用 .native,监听组件根元素上的点击事件 -->
<MyComponent @click.native="handleClick" />
</div>
</template>
<script>
import MyComponent from './MyComponent.vue'
export default {
components: {
MyComponent
},
methods: {
handleClick() {
console.log('点击了!')
}
}
}
</script>
在上面的例子中:
- 第一个
MyComponent
使用@click
,由于组件内部没有触发click
事件,所以点击不会触发handleClick
。 - 第二个
MyComponent
使用@click.native
,点击会直接触发handleClick
,因为它绑定了根元素的点击事件。
我希望能帮助大家更好地理解 @click
和 .native
的工作原理。这是我第一次整理这些信息,可能会有不完善或不太准确的地方,欢迎大家指正哦!如果你有任何疑问或是有不同的见解,都非常欢迎在这里分享和讨论,我们一起学习进步!