Vue3 子UI不更新

Vue3 子UI不更新

问题描述

我在使用 v-model 时遇到了困难。

基本上,我有一个 Parent 组件,它可以拥有多个 Child 实例。单独使用Child正常工作,我希望Parent能够跟踪Child的所有值,并以某种自定义的格式输出值数组。

这种方式有点奏效,但是删除子组件时会出现一些奇怪的行为。

Vue3 子UI不更新

当我移除第一个条目时,数据如预期中的是 [''] . 但是在视觉上,我看到的是错误的子组件被移除了。有什么想法是怎么回事吗?

Vue3 子UI不更新

Child.vue

<script setup>
import { ref, watch, defineProps } from 'vue';
const { modelValue } = defineProps(['modelValue']);
const emitUpdate = defineEmits(['update:modelValue']);
const category = ref(0);
const foods = ref(0);

// Emit new value when user picks a new food
watch(foods, () => {
    emitUpdate('update:modelValue', `{category.value}{foods.value}`);
});
</script>

<template>
    <div>
        <select v-model="category">
            <option value="Fruits">Fruits</option>
            <option value="Pasta">Pasta</option>
        </select>
        <select v-model="foods">
            <option value="oranges">Oranges</option>
            <option value="lasagna">Lasagna</option>
        </select>
    </div>
</template>

Parent.vue

<script setup>
import Child from './Child.vue';
import { ref, defineProps } from 'vue';
const props = defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);

const children = ref([]);

function addChild() {
    children.value.push({ value: '' });
}

function removeChild(index) {
    children.value.splice(index, 1);
    emit('update:modelValue', children.value.map(child => child.value));
}

function updateChildValue(index, value) {
    children.value[index].value = value;
    emit('update:modelValue', children.value.map(child => child.value));
}
</script>

<template>
    <div>
        <button @click="addChild">Add child</button>
        <div v-for="(child, index) in children" :key="index">
            <Child v-model="child.value" @update:modelValue="updateChildValue(index, $event)" />
            <button @click="removeChild(index)">Remove child</button>
        </div>
    </div>
</template>

使用方法

import Parent from '@/components/Parent.vue';
const myParentValue = ref('') 

<template>
        ...
        PARENT
        <Parent v-model="myParentValue"></Parent>
        myParentValue: {{ myParentValue }}
        ...
</template>
...

解决方案

不要将index作为你的v-for指令的key。key应该是唯一的值。当你的数组有元素被添加或移除时,每个index上的项可能会改变,所以index不是给定项的唯一标识符。这就是为什么UI没有正确更新的原因。Vue不能根据key正确地区分数组的变化。 。我建议在添加一个新的子元素时添加一个唯一的id字段。这是一种可能简单的实现方式:

let count = 0
function addChild() {
    children.value.push({ id: count++, value: '' });
}

然后只需要更新你的 v-for:

<div v-for="(child, index) in children" :key="child.id">

还发现了另外两个不重要的问题:

首先,在Child.vue中:

const { modelValue } = defineProps(['modelValue']);

你不应该解构 defineProps。这样做可能会导致响应性丢失。最好将 defineProps 的返回值赋给一个变量,例如 const props = defineProps。目前你的代码中并不会造成问题,因为你在 Child 组件中实际上并没有使用 modelValue…如果你愿意的话,可以删除这个 prop,以及父组件中 <Child> 元素上的 v-model,因为它们实际上并没有做任何事。真正起作用的是 emits。

其次,这不是一个问题,但你不需要导入 defineProps,它在 script setup 中是自动可用的。

所有的修正都可以在这个 Vue Playground 示例中看到。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

Vue3 精选笔记