vue3记el-upload上传图片删除的坑

787 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第27天,点击查看活动详情

写在前面

这篇文章记录我在使用el-upload时删除图片时遇到的一些坑,导致删除文件异常。

坑1 文件数据删除,页面图片还在

正常上传图片之后,点击删除按钮,图片没有删除,但是文件列表已经清空了,效果如下:

image.png

这是因为文件的file-list绑定的数据没有响应式。需要将file-list="fileListCopy.data"改为v-model:file-list="fileListCopy.data"

解决方案

原来的代码:

<el-upload
      action="#"
      :headers="headers"
      :list-type="listType"
      :http-request="uploadAction"
      :on-exceed="handleExceed"
      :on-remove="handleRemove"
      :before-upload="beforeUpload"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :on-progress="uploadProgress"
      file-list="fileListCopy.data"
      ref="upload"
      :multiple="true"
      :limit='limit'
      :disabled="disabled"
      :data="paramData"
    >
    <el-icon><Plus /></el-icon>
    <template #file="{ file }">
      <div>
        <img :src="file.url" alt="" />
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
          >
            <el-icon><zoom-in /></el-icon>
          </span>
          <span
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><Delete /></el-icon>
          </span>
        </span>
      </div>
    </template>
    </el-upload>
    <el-dialog v-model="previewVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>

改为现在的代码:

<el-upload
      action="#"
      :headers="headers"
      :list-type="listType"
      :http-request="uploadAction"
      :on-exceed="handleExceed"
      :on-remove="handleRemove"
      :before-upload="beforeUpload"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :on-progress="uploadProgress"
      v-model:file-list="fileListCopy.data"
      ref="upload"
      :multiple="true"
      :limit='limit'
      :disabled="disabled"
      :data="paramData"
    >
    <el-icon><Plus /></el-icon>
    <template #file="{ file }">
      <div>
        <img :src="file.url" alt="" />
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
          >
            <el-icon><zoom-in /></el-icon>
          </span>
          <span
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><Delete /></el-icon>
          </span>
        </span>
      </div>
    </template>
    </el-upload>
    <el-dialog v-model="previewVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>

移除文件代码

const handleRemove = (file, fileList) => {
  const indexVal = fileListCopy.data.findIndex(item => {
    console.log('item.uid', item.uid);
    console.log('file.uid', file.uid);
    console.log('item.uid === file.uid', item.uid === file.uid);
    return item.uid === file.uid;
  });
  if (indexVal >= 0) {
    fileListCopy.data.splice(indexVal, 1);
  }
};

上述代码也可以简写成这样

const handleRemove = (file, fileList) => {
  console.log('fileList', fileList);
  fileListCopy.data = fileListCopy.data.filter(item => {
    return item.uid !== file.uid;
  });
  console.log('fileListCopy.data', fileListCopy.data);
};

坑2 超出文件格式大小限制时,正常图片无法正常显示

上传了一张正常图片,再上传一张格式错误的照片,文件列表有数据,但是正常图片无法正常显示,效果如下:

image.png

这是因为上传格式错误的图片时会自动触发删除文件的钩子handleRemove,这时候绑定的fileList里面没有url的参数,而且又不是强响应式的,因此原来的图片路径就不存在了。

小结

多张图片的文件删除参考第一种方式。