Vue3组合式API:子组件触发事件时父组件方法调用测试失败求助
问题分析与修复
你遇到的测试失败有几个关键原因,逐个排查修复:
1. <script setup> 方法无法通过 wrapper.vm 访问
Vue3 的 <script setup> 是语法糖,内部定义的函数(比如selectVirtualDevices)默认是闭包私有状态,不会挂载到组件实例(wrapper.vm)上,因此vi.spyOn(wrapper.vm, 'selectVirtualDevices')找不到目标方法,spy 自然不会被触发。
修复方案:
用defineExpose把方法暴露给测试环境:
<!-- Parent.vue --> <template> <ChildComponent @select-devices="selectVirtualDevices" /> </template> <script lang="ts" setup> const selectVirtualDevices = (devices) => { // 原有业务逻辑 } // 暴露方法供测试调用 defineExpose({ selectVirtualDevices }) </script>
2. 事件名不匹配
父组件模板绑定的是@select-devices(短横线命名),但子组件emit的是selectDevices(驼峰命名),Vue3 中事件名大小写敏感,两者无法匹配,导致父组件方法不会被触发。
修复方案:
统一事件命名规则,推荐模板用短横线、emit对应短横线:
<!-- ChildComponent.vue --> <script setup lang="ts"> import { computed, ref } from 'vue' // 修改emit定义为短横线命名 const emit = defineEmits(['select-devices']) const selectedDevices = computed({ get() { return state.selectedDevices }, set(device) { // 对应emit短横线事件名,同时修正参数错误:原代码用了未定义的devices,应为device emit('select-devices', device) }, }) </script>
测试代码中 emit 的事件名同步修改:
wrapper.findComponent(ChildComponent).vm.$emit('select-devices')
3. 测试代码组件查找错误
报错行显示你用了wrapper.findComponent(DevicesDataTable),但导入的组件是ChildComponent,这会导致找不到目标子组件,emit 操作根本没作用在正确的组件上。
修复方案:
把测试代码中的组件查找对象改为ChildComponent:
it('should call selectVirtualDevices', () => { const spy = vi.spyOn(wrapper.vm, 'selectVirtualDevices') // 修正组件查找对象 wrapper.findComponent(ChildComponent).vm.$emit('select-devices') expect(spy).toHaveBeenCalled() })
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

