比如下面的例子:
<GroupCard
v-for="(group, i) in groups"
:key="group.groupName"
v-model="groups[i]"
:available-samples
class="min-h-[216px] min-w-[296px]"
@remove-group="groups.splice(i, 1)"
/>
每个
groups[i]
本身是类型的嵌套对象
{
groupName: string;
sampleNames: string[];
}
groups
是一个ref(实际上是一个v模型本身,它源于表单的表单状态)。
GroupCard
修改它接收到的 group prop 的 groupName
和 sampleNames
字段。反应性有效并且父组件中的表单状态得到正确更新。
但是,
GroupCard
永远不会发出onUpdate:modelValue
,因为对象引用永远不会改变,而是对象被修改。我看到的一个缺点是,这不允许我们在单元测试中侦听发射上的函数调用。
另一种方法是定义 2 个命名模型,代码行数稍微多一些。一份用于组名称,一份用于样本。
为什么不使用道具?
<script setup>
import { ref, reactive} from 'vue';
import Group from './Group.vue';
const groups = reactive([{
groupName: 'group 1',
sampleNames: [],
},{
groupName: 'group 2',
sampleNames: [],
}]);
const msg = ref('Hello World!')
</script>
<template>
<group v-for="(_, i) in groups" :group="groups[i]"/>
<div>{{ groups }}</div>
</template>
Group.vue
<script setup>
import {ref, watch} from 'vue';
const props = defineProps({group: Object});
const names = ref('');
watch(names, val => {
props.group.sampleNames.length = 0;
props.group.sampleNames.push(...val.split(',').map(v => v.trim()));
});
</script>
<template>
<div>
<input v-model="group.groupName"/>
</div>
<input v-model="names"/>
</template>