调用setValue后Vuetify VCheckbox触发update:modelValue事件报Vue警告
解决Vue测试中复选框setValue时的"update:modelValue"警告
问题描述
当使用Vue Test Utils为Vuetify的VCheckbox设置值时,收到如下警告:
[Vue warn]: Component emitted event "update:modelValue" but it is neither declared in the emits option nor as an "onUpdate:modelValue" prop
相关代码
test.vue
<script setup lang="ts"> import { VForm } from 'vuetify/components' const privacyPolicies = ref<boolean>(false) </script> <template id="register-form"> <VCardText> <VForm id="registerForm" class="mt-4" > <VRow> <VCol cols="12"> <VCheckbox v-model="privacyPolicies" data-privacy-policy /> </VCol> </VRow> </VForm> </VCardText> </template>
test.test.ts
import TestRegister from '@/pages/components/test.vue' ... describe.concurrent('Test.vue', () => { let wrapper: VueWrapper beforeEach(() => { wrapper = mount(TestRegister, { global: { plugins: [ createVuetify({ components, directives }), ], }, }) }) it('test something', async () => { const checkBoxSelector = '[data-privacy-policy]' await wrapper.findComponent<typeof VCheckbox>(checkBoxSelector).setValue(true) }) })
解决方案
方法1:直接更新响应式变量(推荐)
不需要调用setValue,直接更新组件内的响应式变量,再触发DOM更新即可规避警告:
it('test something', async () => { // 先在test.vue中导出响应式变量 // defineExpose({ privacyPolicies }) wrapper.vm.privacyPolicies = true // 等待DOM同步更新 await wrapper.vm.$nextTick() // 断言复选框状态 expect(wrapper.find('[data-privacy-policy]').element.checked).toBe(true) })
需要在test.vue的<script setup>中添加defineExpose导出变量,供测试访问。
方法2:手动触发事件替代setValue
模拟组件的事件触发逻辑,手动调用update:modelValue事件并更新变量:
it('test something', async () => { const checkBox = wrapper.findComponent<typeof VCheckbox>('[data-privacy-policy]') // 触发组件的更新事件 await checkBox.vm.$emit('update:modelValue', true) // 同步更新响应式变量 wrapper.vm.privacyPolicies = true await wrapper.vm.$nextTick() })
方法3:测试时存根VCheckbox并声明emits
如果一定要使用setValue,可以在测试挂载时存根VCheckbox,显式声明它的emits选项:
beforeEach(() => { wrapper = mount(TestRegister, { global: { plugins: [ createVuetify({ components, directives }), ], stubs: { VCheckbox: { template: '<input type="checkbox" :checked="modelValue" @change="$emit(\'update:modelValue\', $event.target.checked)">', props: ['modelValue'], emits: ['update:modelValue'] } } }, }) })
方法4:确保Vuetify组件完整注册
检查测试中全局注册的Vuetify组件是否包含VCheckbox,避免因组件未正确初始化导致的emits缺失:
// 导入所有用到的Vuetify组件 import { VCheckbox, VForm, VCardText, VRow, VCol } from 'vuetify/components' beforeEach(() => { wrapper = mount(TestRegister, { global: { plugins: [ createVuetify({ components: { VCheckbox, VForm, VCardText, VRow, VCol }, directives }), ], }, }) })
内容的提问来源于stack exchange,提问作者gormit
相关产品推荐
相关产品推荐

