嘿社区:)我有一个反应性问题(我认为这与反应性有关)。
我有
FileInput.vue
组件。使用该组件,我将文件上传到项目。添加新图像时,新字段将推送到 form.allImages reactive
数组:
@add="addImageField"
addImageField 函数:
const addImageField = (): void => {
form.allImages.push({ filename: '' });
};
反应数据:
import type { Images } from '@/types/images.d';
interface Work {
allImages: Images[];
}
const form: Work = reactive({
allImages: [{ filename: '' }],
});
当我添加 2 个图像,然后尝试使用以下方法删除第一个图像时:
const deleteImageField = (index: number): void => {
form.allImages.splice(index, 1);
};
第一个块正在正确删除,第二个块到达其位置(这是正确的),但现在第二个图像块需要为空(具有明确的值才能向其添加图像)。
form.allImages
中第二个元素的值是清楚的,但组件块不为空,仍然保留了现在是数组中第一个元素的块的图像。
图片:https://github.com/nuxt/nuxt/assets/73745478/74981582-05ea-4910-9387-7240dc4394c2
https://stackblitz.com/edit/nuxt-starter-qeaaeuf?file=app.vue 这是复制品。
单击
Add Image
块并从您的电脑中选择任何图像,将显示 static favicon.ico
文件仅用于示例。然后会出现 Delete
按钮用于删除该图像。在所有块上方,您可以看到用于跟踪数据的{{ form.allImages }}
数据块。
删除后,值为空的图片块需要为空(不包含任何图片,并且能够让用户上传图片)。
**感谢您的关注。如果可以的话请帮忙:)
附注如果您有任何改进代码的想法,也可以写出来。谢谢。**
v-for
的
key需要与
v-for
位于同一元素上。不仅如此,您 不应该使用 index
作为您的 v-for
键。键应该是唯一的值。当您有一个要添加和删除元素的数组时,每个索引处的项目可能会更改,这意味着索引不是给定项目的唯一标识符。这就是 UI 无法正确更新的原因。 Vue 无法根据键正确区分数组的更改。
纠正此问题的一种简单方法是添加一个基于计数器变量的唯一
id
字段,每次推送到数组时该变量都会增加。
interface Images {
filename: string
id: number
}
let count = ref(0);
const form: Work = reactive({
allImages: [{ id: count.value++, filename: '' }],
});
const addImageField = (): void => {
form.allImages.push({ id: count.value++, filename: '' });
};
那么你的 v-for 应该是:
<div v-for="(image, index) in form.allImages" :key="image.id"
纠正了一些其他问题:
const { text, required, modelValue } = props;
请勿破坏道具。这将导致这些值失去其反应性。如果您使用
setup()
功能,则可以使用 props.propName
访问它们。或者在设置函数之外作为 this.propName
,或者在模板代码中作为 propName
。您也不必从设置函数返回道具。它们会自动为您退回。
您应该重命名自定义按钮组件。 “Button”是 HTML 中原生
<button>
元素的保留名称。