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

Vue 3 Vitest:BaseInput组件v-model的emit触发测试问题

问题:BaseInput组件v-model测试中emit事件未触发?

我正尝试为带有v-model属性的BaseInput组件编写测试,期望组件在输入变化时触发emit事件。但在Vitest框架中更新输入后,似乎没有触发emit。

组件代码

<template>
  <label v-if="label">{{ label }}</label>
  <input
    v-bind="$attrs"
    :value="modelValue"
    :placeholder="label"
    @input="$emit('update:modelValue', $event.target.value)"
    class="field"
  />
</template>

<script>
export default {
  props: {
    label: {
      type: String,
      default: "",
    },
    modelValue: {
      type: [String, Number],
      default: "",
    },
  },
};
</script>

测试代码

import { describe, it, expect, beforeEach } from "vitest";
import { mount } from "@vue/test-utils";
import BaseInput from "@/components/base/BaseInput.vue";

describe("BaseInput", () => {
  let wrapper

  beforeEach(() => {
    wrapper = mount(BaseInput, {
      propsData: {
        label: 'Test Label',
        modelValue: 'Test Value'
      }
    })
  })

  it('emits input value when changed', async () => {
    // Assert input value gets the new value
    await wrapper.find('input').setValue('New Test Value')
    expect(wrapper.find('input').element.value).toBe('New Test Value')

    // Assert input event is emitted
    await wrapper.vm.$nextTick()
    expect(wrapper.emitted().input).toBeTruthy() //this fails
  })

});

测试结果:设置输入值后,组件未触发任何emit事件。

请问如何设置输入,以验证组件能正确触发输入值变化的emit事件?


解决方案

问题核心是测试时检查的事件名称错误:你的组件在输入变化时触发的是update:modelValue事件(Vue 3中v-model的标准绑定事件),但测试代码里却在断言input事件是否存在,这才导致测试失败。

修正后的测试代码如下:

import { describe, it, expect, beforeEach } from "vitest";
import { mount } from "@vue/test-utils";
import BaseInput from "@/components/base/BaseInput.vue";

describe("BaseInput", () => {
  let wrapper

  beforeEach(() => {
    wrapper = mount(BaseInput, {
      props: { // Vue Test Utils 4+推荐用props代替propsData
        label: 'Test Label',
        modelValue: 'Test Value'
      }
    })
  })

  it('emits update:modelValue with new value when input changes', async () => {
    const input = wrapper.find('input')
    await input.setValue('New Test Value')

    // 验证输入框值更新正确
    expect(input.element.value).toBe('New Test Value')

    // 验证update:modelValue事件已触发
    const emitEvent = wrapper.emitted()['update:modelValue']
    expect(emitEvent).toBeTruthy()
    
    // 验证事件携带的参数正确
    expect(emitEvent[0][0]).toBe('New Test Value')
  })
});

额外说明:

  • Vue Test Utils 4及以上版本推荐使用props选项代替propsData,测试代码已做对应调整
  • setValue方法本身会触发input事件并更新DOM,无需额外调用$nextTick(除非存在异步更新逻辑)
  • 除了验证事件是否触发,还需验证事件传递的参数与输入值一致,让测试更严谨

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:30:54