我正在尝试将我的组件迁移到Vue 3中。我发现在如何设置V模型上很混乱,尤其是在嵌套组件上。最初,该复选框不应该被选中,因为我正在从API中检索一个值。我应该在哪里初始设置这个嵌套组件的v-model?
CheckboxFieldComponent.vue
<template>
<div v-show="isVisible">
<FormCheckbox
v-model="booleanFromStoreConvertedToArray"
:input-value="field.model.itemId"
:title="title"
:id="field.valueField.id"
:class="field.model.cssClass"
:name="field.valueField.name"
:checked="true"
:required="required"
:disabled="!isEnabled"
@input="
onInput(value);
$emit('change');
"
@focus="field.tracker.onFocusField(field, value)"
@blur="field.tracker.onBlurField(field, value, errors.value)"
/>
</div>
</template>
<script>
export default {
extends: BaseField,
computed: {
booleanFromStoreConvertedToArray: {
get() {
const isSelected = this.value;
if (isSelected) {
return [this.field.model.itemId];
}
return [];
},
set(value) {
this.value = value.length > 0;
},
},
},
};
</script>
FormCheckbox.vue
<template>
<FormCheckboxBase
:checked="shouldBeChecked"
type="checkbox"
:class="$style.check"
:input-value="inputValue"
:title="title"
:id="id"
:name="name"
:required="required"
v-bind="$attrs"
@updateInput="updateInput"
/>
</template>
<script>
export default {
components: {
FormCheckboxBase,
},
props: {
value: {
type: Array,
default: () => [],
},
inputValue: {
// this is the value that will be assigned to the html element's value-property
type: String,
required: true,
},
title: {
type: String,
required: true,
},
id: {
type: String,
required: true,
},
name: {
type: String,
default: '',
},
required: {
type: Boolean,
default: false,
},
},
computed: {
shouldBeChecked() {
if (!this.value) {
return false;
}
return this.value.includes(this.inputValue);
},
},
methods: {
updateInput(event) {
const { checked, value } = event.target;
const newValue = [...this.value];
let checkLabel;
if (checked) {
checkLabel = 'on';
newValue.push(value);
} else {
checkLabel = 'off';
newValue.splice(newValue.indexOf(value), 1);
}
// this.$emit('input', newValue); <--- This is from Vue 2 which was working
},
},
};
</script>
FormCheckboxBase.vue
<template>
<div :class="$style['form-item']">
<input
:id="id"
:value="inputValue"
@change="updateInput"
:type="type"
v-bind="$attrs"
class="input"
:class="$style.input"
/>
<slot />
</div>
</template>
<script>
export default {
props: {
type: {
type: String,
default: 'checkbox',
},
inputValue: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
id: {
type: String,
required: true,
},
required: {
type: Boolean,
default: false,
},
checkboxList: {
type: Boolean,
default: false,
},
},
methods: {
updateInput(event) {
// this.$emit('updateInput', event); <--- This is From Vue2 Event Emitter
},
},
};
</script>
我只是使用这个Basefield作为扩展组件,这样我就可以触发onInput
事件,当我触发check / input字段时,它会触发两次,并且不会更改值
BaseField.vue
onInput(value) {
this.value = value;
// validate
this.validate();
},
1条答案
按热度按时间mwngjboj1#
如何在组件上执行v-model?
根据official document,组件上的
v-model
将扩展为:因此,如果在
FormCheckbox
上设置v-model
,则必须将modelValue
设置为prop以获取绑定值,并将$emit
update:modelValue
设置为双向绑定。在 FormCheckbox.vue 中更改:
收件人:
复选框嵌套绑定问题
在 FormCheckboxBase.vue 中,如果
<input>
的类型为checkbox,则v-bind:value
不会应用于checked
。你必须在 FormCheckboxBase.vue 中设置v-bind:check
:为什么事件被触发两次?
如果您在
FormCheckbox
上设置@input
,则当复选框checked
更改时将触发。但是,CheckboxFieldComponent.vue 中的this.value
直到@change
被触发才被更改。(onInput
将早于onChanged
触发。)此外,
this.value
将由booleanFromStoreConvertedToArray
的设置器设置。这意味着您还在此v-model
中完成了this.value
的双向绑定。所以你只需要在
booleanFromStoreConvertedToArray
的setter下进行验证:下面是演示:https://codesandbox.io/s/question-77194739-f9wm4g
希望能帮上忙!