[英]vue 3 script setup bind v-model to child custom component multiple checkbox
I have looked at many examples of how to do two-way binding of model data, but examples with text inputs are reported everywhere.我看过许多关于如何对 model 数据进行双向绑定的示例,但是到处都报告了带有文本输入的示例。 I work according to the same scheme and get errors.
我按照相同的方案工作并得到错误。
const models = ref({
teams: {
items: usePage().props.value.teams,
selected: [],
isCheckAll: false,
},
});
<template>
<LineTeamsIndex
v-model:selected-items="models.teams.selected"
v-model:isCheckAll="models.teams.isCheckAll"
:teams="$page.props.teams"
@checkAll="checkAll"
>
</LineTeamsIndex>
</template>
child孩子
<script setup>
defineEmits(["update:selectedItems", "update:isCheckAll", "checkAll"]);
const props = defineProps({
teams: Object,
selectedItems: Object,
isCheckAll: Boolean,
});
</script>
<template>
<template v-slot:body>
<tr v-for="team in $page.props.teams.data" :key="team.id">
<td>
<div class="form-check font-size-16">
<input
:id="team.id"
:value="team.id"
:checked="selectedItems.includes(team.id)"
@change="
$emit(
'update:selectedItems',
$event.target.value
)
"
class="form-check-input"
type="checkbox"
/>
</div>
</td>
<td>{{ team.id }}</td>
<td>
{{ team.name }}
</td>
</tr>
</template>
</template>
Here is a part of the code related to the SelectedItems array.这是与 SelectedItems 数组相关的部分代码。 Two-way binding via the built-in v-model is required.
需要通过内置的 v-model 进行双向绑定。 But it either doesn't work, or I get a data mismatch error " [Vue warn]: Invalid prop: type check failed for prop "SelectedItems". Expected Object, got String with value "88"".
但它要么不起作用,要么我收到数据不匹配错误“[Vue 警告]:无效的道具:道具“SelectedItems”的类型检查失败。预期 Object,得到值为“88”的字符串。 Tell me how to correctly transfer (use) the built-in v-model vue 3 to add data to the array and delete using concise code?
告诉我如何正确调用(使用)内置的v-model vue 3 使用简洁的代码向数组中添加数据和删除? Despite the fact that in the child component I have 2 models (not one) that are bound in the parent component.
尽管在子组件中我有 2 个模型(不是一个)绑定在父组件中。
Sounds like it's a prop data type issue.听起来这是一个道具数据类型问题。 You're saying that
selectedItems
should be a Javascript Object
when passing it as a prop, but you're passing String
instead.您是说
selectedItems
在作为道具传递时应该是 Javascript Object
,但是您传递的是String
。
Either change the expected data type:更改预期的数据类型:
defineEmits(["update:selectedItems", "update:isCheckAll", "checkAll"]);
const props = defineProps({
teams: Object,
selectedItems: String, // This is changed to 'String'
isCheckAll: Boolean,
});
or pass the value through as an object instead:或将值作为 object 传递:
v-model:selected-items="{slectedItems: models.teams.selected}"
When you emit $event.target.value
it's the string value of the checkbox (equal to team.id), but the v-model is an array and you can't assign a string to an array.当您发出
$event.target.value
时,它是复选框的字符串值(等于 team.id),但 v-model 是一个数组,您不能将字符串分配给数组。 You need to instead emit an array with all the checkbox values that the v-model should contain.您需要发出一个数组,其中包含 v-model 应包含的所有复选框值。
Instead of emitting from the template, call a method on @change
:不要从模板发出,而是在
@change
上调用方法:
<input
:id="team.id"
:value="team.id"
:checked="selectedItems.includes(team.id)"
@change="updateSelection($event.target.value)"
class="form-check-input"
type="checkbox"
/>
In the method, make a shallow copy of the prop array.在该方法中,制作 prop 数组的浅拷贝。 Push or splice the updated checkbox value to/from the array.
将更新的复选框值推送或拼接到数组中。 Emit that array with your
@update:selectedItems
event.使用您的
@update:selectedItems
事件发出该数组。 I also include one way you might update the isCheckAll
v-model我还包括了一种可以更新
isCheckAll
v-model 的方法
const updateSelection = checkboxVal => {
const selectedItemsCopy = [...props.selectedItems];
const index = selectedItemsCopy.indexOf(checkboxVal);
if (index !== -1) {
selectedItemsCopy.splice(index, 1);
} else {
selectedItemsCopy.push(checkboxVal);
}
emit('update:selectedItems', selectedItemsCopy);
if (selectedItemsCopy.length === props.teams.data.length) {
emit('update:isCheckAll', true);
} else {
emit('update:isCheckAll', false);
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.