elementui el-upload实现图片列表展示、上传和删除

halohalohalo好久不见

业务需求

增加和修改内容中包含一个图片路径列表,需要对图片列表进行展示和操作(添加、预览、查看大图、下载、删除)

分析

  • 弹出框中使用el-upload组件展示和操作图片列表,参考效果:https://element.eleme.io/#/zh-CN/component/upload#wen-jian-suo-lue-tu
  • 关闭弹出框/点击取消时,需要将此次图片列表新增的图片删去,释放存储空间
  • 相较于新增弹出框,修改弹出框需要事先展示从后端获取到的图片列表,因此需要两个el-upload标签来分类

接口需求

  • 添加图片POST
  • 删除图片DELETE
  • 查询图片GET

其中,el-upload添加图片使用组件参数方式设置,查询亦是无需手动获取。删除需要手动。

image-20241021201854790

1
imgUrl: process.env.VUE_APP_BASE_API + "/system/deviceFault/uploadPhoto"

接下来分新增和修改两种来阐述代码构建过程

新增

首先,这是一个图片列表,可以上传多张图片,所以设置好multiple支持多张图片\list-type图片展示方式\file-list绑定图片列表数据\limit图片数量限制@exceed超出限制回调。

其次,像后端上传图片有指定路径,且一般有认证请求头,所以设置好header请求头\imgUrl路径。

随后,图片上传成功需要有一个回调来展示回显图片列表,所以设置好@success上传成功后回调。

然后,对图片的操作需要几个回调,分别是查看大图、下载和删除。

最后,弹出框关闭或点击取消时,上传成功的文件列表需要删掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 <-! 可以使用 v-else 分一波新增upload还是删除uplaod -->
<el-upload
:action="imgUrl"
:headers="{ Token: Token }"
list-type="picture-card"
:on-success="handleUploadSuccess"
multiple
:file-list="picList"
:limit="4"
:on-exceed="handleExceed"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{ file }">
<img
class="el-upload-list__item-thumbnail"
:src="file.url"
alt=""
/>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in"></i>
</span>
<span
class="el-upload-list__item-delete"
@click="handleDownload(file)"
>
<i class="el-icon-download"></i>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<-! 大图预览弹框 -->
<el-dialog :visible.sync="previewOpen">
<img width="100%" :src="previewImgUrl" alt="" />
</el-dialog>

/* 添加/修改弹框中的附件处理 */
// 添加-@success
handleUploadSuccess(response, file, fileList) {
this.picList = fileList;
},
// 添加-@delete
handleRemove(file) {
this.picList.forEach((item, index) => {
if (item.name == file.name) {
let pos = item.response.data.lastIndexOf("/");
let name = item.response.data.slice(pos + 1);
// 接口-根据文件名删除图片
deletePhoto(name).then((res) => {
this.picList.splice(index, 1);
});
}
});
},
// 附件数量超出
handleExceed() {
this.$message({
message: "最多只能上传4张照片",
type: "warning",
});
return;
},
// 图片预览
handlePictureCardPreview(file) {
this.previewImgUrl = file.url;
this.previewOpen = true;
},
// 图片下载
handleDownload(file) {
if (file.url.startsWith("blob")) {
// 添加
var link = document.createElement("a");
link.href = file.url;
link.download = "附件图片.png";
link.click();
link.remove();
} else {
// 修改
fetch(file.url)
.then((response) => response.blob())
.then((blob) => {
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = "附件图片.png";
link.click();
link.remove();
URL.revokeObjectURL(url);
})
.catch((error) => console.error(error));
}
},
// 非确认操作式关闭对话框回调
cancel() {
this.open = false; // 关闭对话框
// 清除增加弹框中的图片列表
if (this.picList && this.picList.length > 0) {
cancelAndDelete(this.picList)
}
// 同样的方式清除修改弹框中的新增的图片列表addUpdateFileList(省略)
function cancelAndDelete(list) {
let deletePromises = list.map((item) => {
let pos = item.response.data.lastIndexOf("/");
let name = item.response.data.slice(pos + 1);
return deletePhoto(name);
});
Promise.all(deletePromises).catch((error) => {
console.error(error);
});
}
}

修改

与新增稍有出入的是:修改弹出框需要先展示已存在的图片链接。

因此,删除当删除这样一个图片列表中的数据时,需要现根据当前图片是否属于本地图片来分类操作。

特别的,因为表单非确认式关闭实际上是不进行增改操作的,所以这里el-upload中绑定的回调实际是伪删除,当确认/非确认时,再批量执行真实请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 获取
getRow(id) {
getRow(id).then((res) => {
this.updateList = res.pics.map(item => {
name: item.name,
url: item.url
})
})
}
// 修改故障-@success
handleUploadSuccess1(response, file, fileList) {
this.updateFileList = fileList;
// 新增的图片列表,为了方便点非确认式关闭对话框时把新增的图片删去
this.addUpdateFileList.push(file);
},
// 修改故障-@delete
handleRemove1(file) {
this.updateFileList.forEach((item, index) => {
if (item.name == file.name) {
// 更新等待删除列表
this.deleteUpdateFileList.push(
// 更新图片列表
this.updateFileList.splice(index, 1)[0]
);
}
});
},
// 确认式
saveForm() {
// 1.修改
// 保存表单请求...
// 👆updateFileList这个list由两种图片数据组成,一种是已存在的后端链接,一种是新增本地的链接
// 👆所以要有一个判断,是使用.response.data还是.url
// 👆记得把数据处理成请求参数格式
// 删除等待删除列表中的所有图片,将deleteUpdateFileList遍历删除
// 关闭对话框
// 清理一下表单数据
// 2.添加
// 保存表单请求,清理表单数据,也就是把这个弹出框所用到的数据给置空
}