如何在Vue的@click事件中获取触发事件的组件引用?
解决Vue+Ionic中点击自定义组件无法获取绑定事件元素引用的问题
问题分析
点击自定义组件SummaryCard或ion-item时,e.target返回的是卡片内部的子元素(标题、副标题等),这是因为事件冒泡机制:触发事件的最内层元素会作为target,而绑定事件的元素是事件冒泡链上的一环,需要用currentTarget来获取它的引用。
解决方案
方案1:使用事件对象的currentTarget
直接在事件处理函数中替换e.target为e.currentTarget,它始终指向绑定当前事件的DOM元素:
const handleCardClick = async (e: Event) => { // 类型断言确保是HTMLElement,方便调用滚动方法 const cardEl = e.currentTarget as HTMLElement; // 执行滚动到视图操作,可配置滚动行为和对齐方式 cardEl.scrollIntoView({ behavior: 'smooth', block: 'start' }); };
注意:如果
SummaryCard是多根节点的组件,currentTarget可能指向Vue的片段容器,此时需要改用方案2。
方案2:在自定义组件内部传递根元素引用
如果SummaryCard是多根组件,或者需要更精准控制传递的元素,可以在组件内部触发click事件时主动传递根元素:
在SummaryCard组件中:
<template> <!-- 假设根元素是你需要滚动的容器,比如ion-card --> <ion-card ref="cardRoot" @click="handleClick"> <!-- 卡片内容:标题、副标题等 --> </ion-card> </template> <script setup lang="ts"> import { ref, defineEmits } from 'vue'; const emit = defineEmits(['click']); const cardRoot = ref<HTMLElement | null>(null); const handleClick = () => { if (cardRoot.value) { // 将根元素作为参数emit出去 emit('click', cardRoot.value); } }; </script>
父组件中接收并使用:
<SummaryCard class="summary" :post="item" @click="handleCardClick" <!-- 其他属性 --> />
const handleCardClick = async (cardEl: HTMLElement) => { cardEl.scrollIntoView({ behavior: 'smooth', block: 'start' }); };
方案3:给目标元素添加ref并通过列表索引获取
如果是在v-for循环中,可以给每个ion-item或SummaryCard添加ref,通过索引获取对应元素:
父组件模板:
<ion-list lines="none" v-for="(item, index) in uiPosts" :key="item.createdAt"> <ion-item v-if="!item.skipped" class="ion-no-padding" :ref="el => { if (el) itemRefs[index] = el }"> <SummaryCard class="summary" :post="item" @click="() => handleCardClick(index)" /> </ion-item> </ion-list>
脚本部分:
import { ref } from 'vue'; const itemRefs = ref<HTMLElement[]>([]); const handleCardClick = async (index: number) => { const targetEl = itemRefs.value[index]; if (targetEl) { targetEl.scrollIntoView({ behavior: 'smooth', block: 'start' }); } };
注意事项
- 使用
scrollIntoView时,可通过behavior(滚动行为)和block(对齐方式)参数优化滚动体验; - 如果使用Ionic的
ion-content滚动容器,也可结合其内置的滚动方法,但核心仍需拿到目标元素的引用。
内容的提问来源于stack exchange,提问作者learnvst
相关产品推荐
相关产品推荐

