2025年vue element-ui 的 upload 组件上传图片列表出错后多删除了一张图片(原因分析及解决方法)

vue element-ui 的 upload 组件上传图片列表出错后多删除了一张图片(原因分析及解决方法)背景 最近使用 element ui 的 upload 组件上传图片列表 发现当选择上传的图片出错时 会将上一张图片删除了 效果如下 代码 lt template gt lt el upload action action file list

大家好,我是讯享网,很高兴认识大家。

背景

最近使用 element-uiupload 组件上传图片列表,发现当选择上传的图片出错时,会将上一张图片删除了。

效果如下:
在这里插入图片描述
讯享网
代码:

<template> <el-upload :action="action" :file-list="fileList" list-type="picture" :on-remove="handleRemove" :before-upload="beforeUpload" > <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip"> <p>1. 只能上传 jpg / png 文件,且不超过 500 kb;</p> <p>2. 建议上传图片的长宽比为1.5 : 1;</p> </div> </el-upload> </template> <script> export default { 
     name: "uploadImageList", props: { 
     action: { 
     type: String, }, imageUrlList: { 
     type: Array, }, }, data() { 
     return { 
     fileList: [], limit: 4, }; }, watch: { 
     imageUrlList(list) { 
     this.fileList = []; list.forEach((element) => { 
     this.fileList.push({ 
     name: element, url: `${ 
      this.$store.state.server_url}/upload/${ 
      element}`, }); }); }, }, mounted() { 
     this.imageUrlList.forEach((element) => { 
     this.fileList.push({ 
     name: element, url: `${ 
      this.$store.state.server_url}/upload/${ 
      element}`, }); }); }, methods: { 
     beforeUpload(file) { 
     const isJPG = file.type === "image/jpeg"; const isLt2M = file.size / 1024 / 1024 < 0.5; if (!isJPG) { 
     this.$message.error("上传头像图片只能是 JPG 格式!"); } if (!isLt2M) { 
     this.$message.error("上传图片大小不能超过 500 kb!"); } return isJPG && isLt2M; }, handleRemove(file) { 
     this.$emit("delUploadImage", file.name); }, }, }; </script> 

讯享网

原因分析

上面代码中,在 beforeUpload 事件中添加用户上传文件的判断操作。但该事件放回 false 时,会自动终止上传事件。但是呢!由于 上传失败后,组件会自动执行 on-remove 事件。而我这里因为需求的原因设置on-remove 会触发父组件的 delUploadImage 事件,导致了多删除了一次。所以就用上面这种情况出现了。

要点:


beforeUpload 事件返回 false 时, element-ui 组件 upload 会自动执行一次 on-remove 事件。

解决方法

1. 不自定义 on-remove 事件

这一点就不用分析了。前面提到,出现这个的原因是系统自动调用了 on-remove 事件。不自定义 on-remove 事件,让系统执行默认的 on-remove 方法。也就不会出现冲突了。

2. 在 on-remove 事件中添加判断,区分已上传的图片和出错的图片

第一种方法虽然简单,但是很多情况下,不得不自定义 on-remove 事件。那这是我们就需要在 on-remove 事件做个判断了。判断如果要删除的文件是错误的文件,就不执行自定义的 on-remove 的方法。
例如:


因为上传成功的图片都会存放到 file-list 属性中,那我们只需判断要删除的图片是否在其中就好了。

讯享网handleRemove(file) { 
    if(this.imageUrlList.indexOf(file) > -1){ 
    this.$emit("delUploadImage", file.name); } } 

3. 不使用 beforeUpload 事件来判断上传文件是否符合要求

不适用 beforeUpload 来判断,那就不会自动执行 on-remove 事件。

那判断该在哪里进行了?

我们可以在用户选择文件后读取文件信息来进行判断,而不是在上传前来进行判断。可以在upload 组件的 on-change 事件中进行。

参数 说明 类型
on-change 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 function(file, fileList)

这里涉及到三点

  1. 判断的时机,on-change 事件
  2. 停止 upload 组件的选中文件后默认进行上传的功能。这个可用通过设置 auto-upload属性来关闭
    参数 说明 类型
    auto-upload 是否在选取文件后立即进行上传 boolean
  3. 判断通过后,怎么触发上传事件?可以通过 submit 方法来实现。
    方法名 说明 参数
    submit 手动上传文件列表

关于第三点,需要讲解一下如何调用 submit 方法:

upload 如何使用 Methods 里的方法

关于这一点,其实只要我们明白一点就行了。

element-ui 是什么?

element-ui 是 vue 的第三方组件库。

也就是说,upload 是一个组件。那我们想要在当前组件中调用 upload 的方法,不就变成了父组件调用子组件的方法的问题了吗?

更多关于 vue 父子组件的通讯可以参考:《Vue 的父组件和子组件之数据传输、方法互调》 、《Vue 组件间通讯之非父子组件间通讯——事件总线(EventBus)》

所以我们可以这么做:

<template> <el-upload ref="uploadList" :action="action" :file-list="fileList" :auto-upload="false" list-type="picture" :on-change="change" :on-remove="handleRemove" > <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip"> <p>1. 只能上传 jpg / jpeg / png 文件,且不超过 500 kb;</p> <p>2. 建议上传图片的长宽比为1.5 : 1;</p> </div> </el-upload> </template> <script> export default { 
     name: "uploadImageList", props: { 
     action: { 
     type: String, }, imageUrlList: { 
     type: Array, }, }, data() { 
     return { 
     fileList: [], }; }, watch: { 
     imageUrlList(list) { 
     this.fileList = []; list.forEach((element) => { 
     this.fileList.push({ 
     name: element, url: `${ 
      this.$store.state.server_url}/upload/${ 
      element}`, }); }); }, }, mounted() { 
     this.imageUrlList.forEach((element) => { 
     this.fileList.push({ 
     name: element, url: `${ 
      this.$store.state.server_url}/upload/${ 
      element}`, }); }); }, methods: { 
     change(file, fileList){ 
     const typeList = ["image/jpeg","image/png", "image/jpg"] const isLt2M = file.raw.size / 1024 / 1024 < 0.5; if (typeList.indexOf(file.raw.type) < 0) { 
     this.$message.error("上传图片只能是 jpg / png / jpeg 格式!"); fileList.pop(); this.fileList = fileList; return false; } if (!isLt2M) { 
     this.$message.error("上传图片大小不能超过 500 kb!"); fileList.pop(); this.fileList = fileList; return false; } this.$refs['uploadList'].submit(); }, handleRemove(file) { 
     this.$emit("delUploadImage", file.name); }, }, }; </script> 

修改后,效果如下:在这里插入图片描述

完整的组件代码如下:

讯享网<template> <el-upload ref="uploadList" class="text-l" :action="action" :file-list="fileList" :auto-upload="false" list-type="picture" :limit="limit" :on-change="change" :on-exceed="handleExceed" :on-remove="handleRemove" :on-success="handleSuccess" > <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip"> <p>1. 只能上传 jpg / jpeg / png 文件,且不超过 500 kb;</p> <p>2. 建议上传图片的长宽比为1.5 : 1;</p> </div> </el-upload> </template> <script> export default { 
     name: "uploadImageList", props: { 
     action: { 
     type: String, }, imageUrlList: { 
     type: Array, }, }, data() { 
     return { 
     fileList: [], limit: 4, }; }, watch: { 
     imageUrlList(list) { 
     this.fileList = []; list.forEach((element) => { 
     this.fileList.push({ 
     name: element, url: `${ 
      this.$store.state.server_url}/upload/${ 
      element}`, }); }); }, }, mounted() { 
     this.imageUrlList.forEach((element) => { 
     this.fileList.push({ 
     name: element, url: `${ 
      this.$store.state.server_url}/upload/${ 
      element}`, }); }); }, methods: { 
     change(file, fileList){ 
     const typeList = ["image/jpeg","image/png", "image/jpg"] const isLt2M = file.raw.size / 1024 / 1024 < 0.5; if (typeList.indexOf(file.raw.type) < 0) { 
     this.$message.error("上传图片只能是 jpg / png / jpeg 格式!"); fileList.pop(); this.fileList = fileList; return false; } if (!isLt2M) { 
     this.$message.error("上传图片大小不能超过 500 kb!"); fileList.pop(); this.fileList = fileList; return false; } this.$refs['uploadList'].submit(); }, handleExceed() { 
     this.$message({ 
     message: `一个商品只能添加${ 
      this.limit}张图片。`, type: "warning", }); }, handleSuccess(res, file, fileList) { 
     console.log(fileList); console.log(res); fileList.forEach((element) => { 
     if (element.response) { 
     element.name = element.response.data; this.imageUrlList.push(element.response.data); } }); this.$emit("updateImgSrcList", this.imageUrlList); }, handleRemove(file) { 
     this.$emit("delUploadImage", file.name); }, }, }; </script> 
小讯
上一篇 2025-01-11 19:21
下一篇 2025-03-02 22:48

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/119761.html