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

Vue2单元测试中无法获取动态子组件实例触发自定义事件如何解决

报错核心原因

你遇到的Cannot read properties of undefined (reading '$emit')报错,本质是查找操作执行时,动态组件还未完成挂载,或者你使用的查找方法不对,没有拿到正确的组件实例。

可行解决方案

方案1:直接通过父组件$refs获取动态组件实例(最推荐)

你在模板上已经给动态组件声明了ref="dynamicComponent",可以直接从父组件实例的$refs属性取值,不需要通过find/findComponent查找,代码如下:

// 先确保父组件的someDynamicType已经赋值为目标子组件类型
wrapper.vm.someDynamicType = KnownSubType
// 等待Vue异步更新队列执行完成,动态组件挂载完毕
await wrapper.vm.$nextTick()
// 直接通过refs拿到子组件实例触发事件
wrapper.vm.$refs.dynamicComponent.$emit('custom-event', {})

注意:如果动态组件初始是未渲染状态,必须先给someDynamicType赋值,等更新完成再操作。

方案2:修正查找方法获取组件实例

如果你要通过查找API获取,注意以下两点:

  1. 不要用find方法查找组件,find返回的是DOM元素包装器,没有vm属性,查找组件必须用findComponent
  2. 查找前必须等待动态组件挂载完成

修正后的代码示例:

wrapper.vm.someDynamicType = KnownSubType
await wrapper.vm.$nextTick()
// 按组件类型查找
await wrapper.findComponent(KnownSubType).vm.$emit('custom-event', {})
// 或者按ref查找
await wrapper.findComponent({ref: 'dynamicComponent'}).vm.$emit('custom-event', {})

方案3:Stub动态组件简化测试

如果你不需要测试子组件本身的逻辑,可以在挂载父组件时提前Stub动态组件,保证查找时一定能命中:

import { mount } from '@vue/test-utils'
import ParentComponent from './ParentComponent.vue'
import KnownSubType from './KnownSubType.vue'

const wrapper = mount(ParentComponent, {
  stubs: {
    // Stub目标子组件
    KnownSubType: {
      name: 'KnownSubType',
      template: '<div></div>'
    }
  },
  data() {
    return {
      // 初始化就指定动态组件类型,避免后续等待更新
      someDynamicType: KnownSubType
    }
  }
})

// 直接触发即可
wrapper.findComponent(KnownSubType).vm.$emit('custom-event', {})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:24:03