Vue.js多图上传预览删除功能单次点击删两张图片的问题如何修复
问题根因
你的代码出现单次删除两张图片的问题,核心是三个错误叠加导致:
- 用数组索引作为
v-for的key属性,Vue在列表元素删除时会复用DOM节点,导致ref和实际数组下标对应关系错乱 - 删除操作执行了两次移除逻辑:
splice已经将目标元素从数组中删除,后续主动将对应下标ref的src设空,配合DOM复用的逻辑,刚好会把原本的最后一张图片的预览也清空,看起来就像删了两张 - 上传文件时每次都遍历整个数组重新读取文件生成预览,会重复覆盖旧的图片预览地址
修复方案
修改思路是把预览地址和文件绑定存储在数组中,完全不需要操作DOM和ref,依托Vue的响应式能力自动更新视图,具体代码如下:
<template> <input id="file-upload" type="file" multiple @change="uploadImage" /> <!-- 用唯一ID作为key,避免DOM复用问题 --> <div v-for="(item, index) in productImages" :key="item.id"> <div class="image-holder"> <!-- 直接绑定存在数组里的预览地址 --> <img :src="item.preview" alt="预览图" /> <button type="button" @click="removeImage(index)">删除</button> </div> </div> </template> <script> export default { data() { return { productImages: [] } }, methods: { uploadImage(e) { const selectedFiles = e.target.files; // 仅处理新选择的文件,不要重复读取旧文件 for (let i = 0; i < selectedFiles.length; i++) { const file = selectedFiles[i]; const reader = new FileReader(); reader.onload = (e) => { this.productImages.push({ id: Date.now() + Math.random(), // 生成唯一ID作为key file: file, preview: e.target.result }) }; reader.readAsDataURL(file); } // 清空input值,允许重复选择同一个文件 e.target.value = '' }, removeImage(index) { // 仅操作数组即可,Vue会自动响应式更新视图 this.productImages.splice(index, 1); } } } </script>
内容的提问来源于stack exchange,提问作者zyyyzzz
相关产品推荐
相关产品推荐

