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获取,注意以下两点:
- 不要用
find方法查找组件,find返回的是DOM元素包装器,没有vm属性,查找组件必须用findComponent - 查找前必须等待动态组件挂载完成
修正后的代码示例:
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
相关产品推荐
相关产品推荐

