测试 v-model
当编写依赖于v-model交互的组件时(更新:modelValue事件),你需要处理事件和props。
查看一些社区解决方案的“vmodel 集成”讨论。
检查VueJS VModel事件文档
简单的例子
这里有一个简单的 Editor 组件:
js
const Editor = {
props: {
label: String,
modelValue: String,
},
emits: ["update:modelValue"],
template: `<div>
<label>{{label}}</label>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</div>`,
};const Editor = {
props: {
label: String,
modelValue: String,
},
emits: ["update:modelValue"],
template: `<div>
<label>{{label}}</label>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</div>`,
};这个组件的行为就像一个input组件:
js
const App {
components: {
Editor
},
template: `<editor v-model="text" label="test" />`,
data(){
return {
text: 'test'
}
}
}const App {
components: {
Editor
},
template: `<editor v-model="text" label="test" />`,
data(){
return {
text: 'test'
}
}
}现在,当我们输入input时,它将更新组件上的文本。
要测试此行为:
js
test("modelValue should be updated", async () => {
const wrapper = mount(Editor, {
props: {
modelValue: "initialText",
"onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
},
});
await wrapper.find("input").setValue("test");
expect(wrapper.props("modelValue")).toBe("test");
});test("modelValue should be updated", async () => {
const wrapper = mount(Editor, {
props: {
modelValue: "initialText",
"onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
},
});
await wrapper.find("input").setValue("test");
expect(wrapper.props("modelValue")).toBe("test");
});多个 v-model
在某些情况下,我们可以有多个针对特定属性的v-model。
例如Money Editor,我们可以有currency和modelValue属性。
js
const MoneyEditor = {
template: `<div>
<input :value="currency" @input="$emit('update:currency', $event.target.value)"/>
<input :value="modelValue" type="number" @input="$emit('update:modelValue', $event.target.value)"/>
</div>`,
props: ["currency", "modelValue"],
emits: ["update:currency", "update:modelValue"],
};const MoneyEditor = {
template: `<div>
<input :value="currency" @input="$emit('update:currency', $event.target.value)"/>
<input :value="modelValue" type="number" @input="$emit('update:modelValue', $event.target.value)"/>
</div>`,
props: ["currency", "modelValue"],
emits: ["update:currency", "update:modelValue"],
};我们可以通过以下方式进行测试:
js
test("modelValue and currency should be updated", async () => {
const wrapper = mount(MoneyEditor, {
props: {
modelValue: "initialText",
"onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
currency: "$",
"onUpdate:currency": (e) => wrapper.setProps({ currency: e }),
},
});
const [currencyInput, modelValueInput] = wrapper.findAll("input");
await modelValueInput.setValue("test");
await currencyInput.setValue("£");
expect(wrapper.props("modelValue")).toBe("test");
expect(wrapper.props("currency")).toBe("£");
});test("modelValue and currency should be updated", async () => {
const wrapper = mount(MoneyEditor, {
props: {
modelValue: "initialText",
"onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
currency: "$",
"onUpdate:currency": (e) => wrapper.setProps({ currency: e }),
},
});
const [currencyInput, modelValueInput] = wrapper.findAll("input");
await modelValueInput.setValue("test");
await currencyInput.setValue("£");
expect(wrapper.props("modelValue")).toBe("test");
expect(wrapper.props("currency")).toBe("£");
});
zerone