You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中如何在@click事件中获取wb-button组件实例?

Vue3 获取循环渲染的自定义组件实例的最优实现

方案1:子组件主动传递实例(推荐)

在wb-button组件内部,获取自身实例并在点击时通过事件传递给父组件,同时暴露需要调用的方法:

<!-- wb-button.vue -->
<template>
  <button @click="handleClick">删除</button>
</template>

<script setup>
import { getCurrentInstance } from 'vue'

const emit = defineEmits(['click'])
const instance = getCurrentInstance()

// 点击时将组件实例作为参数抛出
const handleClick = () => {
  emit('click', instance)
}

// 组件内部的加载状态方法
const putInLoadingStatus = () => {
  // 实现你的加载逻辑
}

// 暴露方法给父组件调用
defineExpose({
  putInLoadingStatus
})
</script>

父组件中直接接收实例并传入处理方法:

<!-- 父组件 -->
<template>
  <wb-button 
    v-for="item in items" 
    :key="item.id" 
    @click="(btnInstance) => deleteItem(item.id, btnInstance)"
  >
    删除{{ item.name }}
  </wb-button>
</template>

<script setup>
const deleteItem = async (itemId, btnInstance) => {
  // 调用子组件的加载方法
  btnInstance.putInLoadingStatus()
  
  try {
    // 执行删除操作,比如调用接口
    // await deleteItemApi(itemId)
    // 删除成功后的逻辑
  } finally {
    // 若需结束加载,可在此调用对应的方法
    // btnInstance.clearLoadingStatus()
  }
}
</script>

优点:组件职责清晰,不依赖内部私有属性,维护成本低,是最符合Vue设计理念的方案。


方案2:通过DOM元素获取组件实例(不推荐)

如果无法修改wb-button组件,可利用Vue挂载到DOM元素上的私有属性__vue__获取实例(注意:该属性为内部实现,未来可能变更,存在兼容性风险):

<!-- 父组件 -->
<template>
  <wb-button 
    v-for="item in items" 
    :key="item.id" 
    @click="(e) => deleteItem(item.id, e.currentTarget.__vue__)"
  >
    删除{{ item.name }}
  </wb-button>
</template>

<script setup>
const deleteItem = async (itemId, btnInstance) => {
  btnInstance.putInLoadingStatus()
  // 执行删除逻辑
}
</script>

缺点:依赖Vue内部实现,生产环境不建议使用。


方案3:利用模板引用数组

通过ref绑定循环组件得到实例数组,再通过DOM元素匹配对应实例:

<!-- 父组件 -->
<template>
  <wb-button 
    v-for="item in items" 
    :key="item.id" 
    ref="btnRefs"
    @click="(e) => deleteItem(item.id, e.currentTarget)"
  >
    删除{{ item.name }}
  </wb-button>
</template>

<script setup>
import { ref } from 'vue'

const btnRefs = ref([])

const deleteItem = async (itemId, targetDom) => {
  // 从ref数组中匹配对应组件实例
  const btnInstance = btnRefs.value.find(inst => inst.$el === targetDom)
  if (btnInstance) {
    btnInstance.putInLoadingStatus()
    // 执行删除逻辑
  }
}
</script>

优点:无需修改子组件;缺点:需要维护ref数组,逻辑相对繁琐。

内容的提问来源于stack exchange,提问作者Mahyar Khanbabai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:33:23