Vue Element-UI 采用 http-request 方式自定义文件上传


Vue 的文件上传组件 upload,拥有支持多种格式文件上传,单文件多文件等都支持,许多项目现在都少不了文件上传功能,但是 vue 的 upload 组件如果直接引用,肯定也有一些不方便之处,有的时候需要传参数,需要手动触发上传方法,而不是选择了文件就上传,所以结合我项目实例,写一 vue 自定义文件上传的实现,包括前端和后台的处理以及参数的接收。

🌞 Vue 界面示例

我这里是富文本中的图片上传,以下教程也同样适用于其他方面,可根据自己需求修改。

🌞 Vue 代码

以下代码可根据自己业务需求进行合理的修改使用。

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
121
122
123
124
125
126
127
128
129
130
<template>
<div class="upload-container">
<el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">
上传
</el-button>
<el-dialog :visible.sync="dialogVisible">
<el-upload
:multiple="true"
:file-list="fileList"
:show-file-list="true"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:http-request="uploadImage"
action="#"
class="editor-slide-upload"
list-type="picture-card"
>
<el-button size="small" type="primary">
点击上传
</el-button>
</el-upload>
<el-button @click="dialogVisible = false">
取消
</el-button>
<el-button type="primary" @click="handleSubmit">
确定
</el-button>
</el-dialog>
</div>
</template>

<script>
import { uploadALocalPicture } from '../../../api/upload'

export default {
name: 'EditorSlideUpload',
props: {
color: {
type: String,
default: '#1890ff'
}
},
data() {
return {
dialogVisible: false,
listObj: {},
fileList: []
}
},
methods: {
// 校验所有文件是否上传成功
checkAllSuccess() {
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
},
// 确定提交事件
handleSubmit() {
// 我这里是将数组递交给父级组件,根据自己的需求进行合理处理
const arr = Object.keys(this.listObj).map(v => this.listObj[v])
// 校验所有文件是否上传成功
if (!this.checkAllSuccess()) {
this.$message('请等待所有图像成功上传。如果出现网络问题,请刷新页面,然后重新上传!')
return
}
// 集合递交给父级组件方法
this.$emit('successCBK', arr)
this.listObj = {}
this.fileList = []
this.dialogVisible = false
},
// 移除文件
handleRemove(file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
delete this.listObj[objKeyArr[i]]
return
}
}
},
// 上传文件前调用的方法,主要为了校验文件
beforeUpload(file) {
if (!(file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/gif')) {
this.$notify.warning({
title: '警告',
message: '上传应用Logo图片只能是 JPG/PNG/JPEG/GIF 格式!'
})
return false
}
},
// 上传文件
uploadImage(param) {
const _self = this
const fileName = param.file.uid
this.listObj[fileName] = {}
const formData = new FormData()
formData.append('picFile', param.file)
// 这里调用的axios封装的请求方法(根据自己项目进行调用)
uploadALocalPicture(formData).then(res => {
// 上传成功的图片会显示绿色的对勾
param.onSuccess()
console.log('上传图片成功')
_self.listObj[fileName] = { hasSuccess: false, uid: param.file.uid }
this.handleSuccess(res, param.file)
})
},
// 上传成功时调用的方法
handleSuccess(response, file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
this.listObj[objKeyArr[i]].url = response.data
this.listObj[objKeyArr[i]].hasSuccess = true
return
}
}
}
}
}
</script>

<style lang="scss" scoped>
.editor-slide-upload {
margin-bottom: 20px;
/deep/ .el-upload--picture-card {
width: 100%;
}
}
</style>

🌞 Java 代码

以下代码各位看个思路就行,具体代码实现根据自己情况而定。

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
package com.scaffolding.demo.sys.controller;

import com.scaffolding.demo.annotation.CheckToken;
import com.scaffolding.demo.annotation.Log;
import com.scaffolding.demo.annotation.PassToken;
import com.scaffolding.demo.common.ErrorCode;
import com.scaffolding.demo.common.OperationLogConstant;
import com.scaffolding.demo.common.Result;
import com.scaffolding.demo.common.ResultGenerator;
import com.scaffolding.demo.config.EnvConfig;
import com.scaffolding.demo.exception.BusinessException;
import com.scaffolding.demo.utils.UuidUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Objects;

/**
* @author: Xuxu
* @date: 2020-01-16 15:41
**/
@Slf4j
@RestController
@RequestMapping("/sys/upload")
@Api(value = "上传文件", tags = "操作上传文件相关API")
@ApiResponses({@ApiResponse(code = 400, message = "请求参数没填好"),
@ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对")
})
public class UploadFileController {

// 获取配置文件中的变量
@Autowired
private EnvConfig envConfig;

/**
* 上传图片
*
* @return
*/
@CheckToken
@PostMapping("/image")
@ApiOperation(value = "上传图片")
@Log(operationModule = "上传图片", operationType = OperationLogConstant.UPLOAD, operationDesc = "上传图片")
public Result<String> uploadImage(@RequestParam("picFile") MultipartFile picFile) {
log.info("开始上传图片");
try {
String showPath = uploadFile(picFile);
return ResultGenerator.genSuccessResult(showPath);
} catch (Exception e) {
log.error("上传图片异常");
e.printStackTrace();
throw new BusinessException(ErrorCode.UPLOAD_IMAGE_ERROR);
}
}

/**
* 上传文件
*
* @param file
* @return
* @throws IOException
*/
private String uploadFile(MultipartFile file) throws IOException {
//获取原始文件名称(包含格式)
String filename = file.getOriginalFilename();
//获取文件类型,以最后一个`.`为标识
String type = filename.substring(Objects.requireNonNull(filename).lastIndexOf(".") + 1);
//文件名
String name = filename.substring(0, Objects.requireNonNull(filename).lastIndexOf("."));
//当前时间戳
long timeMillis = System.currentTimeMillis();
//获取文件在服务器的储存位置
File filePath = new File(envConfig.getUploadPath());
// 是否是文件夹
if (!filePath.exists() && !filePath.isDirectory()) {
System.out.println("目录不存在,创建目录:" + filePath);
filePath.mkdir();
}
//在指定路径下创建一个文件
File newFile = new File(envConfig.getUploadPath(), name + timeMillis + "." + type);
// 上传文件
file.transferTo(newFile);
return envConfig.getShowPath() + name + timeMillis + "." + type;
}

}

评论