最近做一个H5项目,使用的是vue2+vant2+springboot前后端分离架构。有一些选择多张图片上传的需求,做完在这里分享一下
vant2的图片上传组件 van-uploader 组件如下所示:
<van-field
label="问题点图片"
center
required
:left-icon="require('../../assets/u8.svg')"
>
<template #input>
<van-uploader
v-model="fileList"
multiple
accept="image/*"
:max-count="5"
:before-read="beforeRead"
:after-read="afterRead"
:before-delete="beforeDelete" />
</template>
</van-field>
fileList表示图片数据
mutiple 默认为true,多选图片需设置为true
accept=“image/*” 表示只接受图片类型文件
:max-count="5" 限制上传的图片数量
beforeRead 函数表示读取文件前
afterRead 函数表示读取文件后
beforeDelete 函数表示删除文件前
js代码如下:
export default{
data(){
return{
fileList: [], // 已上传的图片
}
},
methods:{
// 文件读取前触发
beforeRead(e) {
if (e.size > 20 * 1024 * 1024) {
this.$toast.fail('文件大小不能超过20M')
return false
}
return true
},
afterRead(file) {
forms = new FormData();
//"file"表示给后台传的属性名字
if (file instanceof Array){
file.forEach(f=>{
forms.append("fileList",f.file)
})
}else {
forms.append("fileList", file.file); //获取上传图片信息
}
this.reportPicUpload()
},
//图片上传,由提交按钮调用本方法实现手动上传
reportPicUpload() {
//如果文件列表为空,则不需要调用上传
if (forms == null || forms.length == 0) {
return;
}
axios({
method: "post",
url: base.SSO_BASEURL + "/app/kb/upload",
data: forms,
params: {
kbId: this.formInfo.sysId
},
headers: {
"content-type": "multipart/form-data",
},
}).then((res) => {
if (res.data.code == 200) {
let files = res.data.data
for (let i = 0; i < files.length; i++) {
let name = files[i].file.substring(files[i].file.lastIndexOf("/")+1)
this.fileList.map(f=>{
if (f.file.name===name){
f.url = files[i].file
}
})
}
} else {
Toast.fail(res.msg);
}
}).catch((err) => {
Toast.fail(err.toString());
});
},
beforeDelete(file) {
forms = null;
this.delFile(this.formInfo.sysId,file.url)
return true;
},
delFile(id,url){
this.$api.kbApi.delFile({id:id,url:url}).then(res=>{
if (res.code==200){
this.getById(id)
}
})
},
}
}
后端接口:
/**
* 快报文件上传接口
* @param map
* @return
*/
@PostMapping("kb/upload")
@RateLimiter(time = 1,count = 10,type = LimiterType.DEFAULT)
public JsonResult upload(MultipartFile[] fileList,@RequestParam Map<String, String> map){
return operationEyeOfHeavenService.upload(fileList,map);
}
接口实现:
@Override
public JsonResult upload(MultipartFile[] fileList, Map<String, String> map) {
log.info("文件上传{}{}",map.get("kbId"),fileList);
List<Map<String,Object>> files = new ArrayList<>();
for (MultipartFile file : fileList) {
try {
String path = "D:/fileUpload/" + "csr" + "/" + "tyxd";
File filePath = new File(path);
if (!filePath.exists() && !filePath.isDirectory()) {
filePath.mkdir();
}
String originalFileName = file.getOriginalFilename();
File targetFile = new File(path, originalFileName);
FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(targetFile));
String fileUrl = "http://****/app" + path.replace("D:", "") + "/" + originalFileName;
Map<String, Object> data = new HashMap<>();
data.put("rs", true);
data.put("file", fileUrl);
addFile(map.get("kbId"), fileUrl);
files.add(data);
} catch (Exception e) {
e.printStackTrace();
return JsonResult.error("上传失败");
}
}
return JsonResult.ok(files);
}
需要注意的是在beforeRead 函数中,做文件校验时别出错,否则选择多张图片后会没反应。