Vitest中触发keyup.enter事件无响应,问题原因是什么?
问题原因
你遇到的问题核心在于Vue测试包装器的trigger方法调用组件实例时,触发的是Vue自定义事件而非原生DOM事件,而浏览器中的正常运行依赖原生事件冒泡机制。
具体细节:
- 父组件在
CustomInput上绑定的@keyup.enter="onUpdate",由于Vue3默认inheritAttrs: true,这个原生事件监听器会自动挂载到CustomInput的根DOM元素(即内部的<div>)。 - 浏览器中,
<input>的keyup.enter原生事件会向上冒泡到根<div>,触发绑定的监听器,进而调用onUpdate。 - 但测试时,你调用
searchField.trigger('keyup.enter')或searchField.trigger('keyup', { key: 'enter' }),都是在CustomInput的Vue组件实例上触发自定义事件,而非触发根DOM元素的原生事件。由于CustomInput并没有定义keyup.enter这个emit事件,父组件的监听器自然不会响应。
解决方法
直接找到CustomInput内部的<input>元素,触发它的原生keyup.enter事件,让事件正常冒泡到根元素:
it('should react to the keyup event', async () => { const props = { /* ... */ } const wrapper = mount(MyMainComponent, {props}); const inputElement = wrapper.findComponent(CustomInput).find('input'); await inputElement.setValue('My search term'); // 直接在input元素上触发原生keyup.enter事件 await inputElement.trigger('keyup.enter'); expect(wrapper.emitted('update')?.length).toBeGreaterThan(0); });
如果需要更严谨地定义组件间的事件传递,也可以修改CustomInput组件,显式将内部input的keyup.enter事件向外emit:
<!-- CustomInput.vue --> <template> <div> <input type="text" @keyup.enter="$emit('keyup.enter')" /> </div> </template>
修改后,测试时调用searchField.trigger('keyup.enter')也能正常触发父组件的onUpdate方法,这种方式适合需要明确暴露子组件内部事件的场景。
内容的提问来源于stack exchange,提问作者Subsurf
相关产品推荐
相关产品推荐

