uni-app H5 上传图片
请注意:前端代码基本来自 官网,以及我个人的使用记录,价值不大,欢迎参考,感谢指正
uni-app H5 上传图片
环境
uni-app
uView2.x - 表单组件 Upload 上传
前端代码
假设分为 新增、编辑、预览、三个操作,则代码实现略有不同
1.仅新增时,初始数据为空、图片文件列表也为空,对源码无需做何修改
2.仅编辑时,初始化需要加载图片列表,加载和上传时需注意 fileList2 中图片地址的问题(如果数据库始终保存完整地址,也无需考虑,请视情况而定)
3.仅预览时,upload组件需隐藏上传按钮、设置maxCount长度、添加disabled属性
<template>
<!-- 新增 -->
<u-upload
:fileList="fileList1" //显示已上传的文件列表
@afterRead="afterRead" //选择图片后,上传事件
@delete="deletePic" //删除图片 事件
name="1" //标识符,可以在回调函数的第二项参数中获取
multiple //是否开启图片多选
:maxCount="10" //最大选择图片的数量
:previewFullImage="true" //是否显示组件自带的图片预览功能,默认为true
></u-upload>
<!-- 编辑 -->
<u-upload
:fileList="fileList2"
@afterRead="afterRead"
@delete="deletePic"
name="2"
multiple
:maxCount="10"
:previewFullImage="true"
></u-upload>
<!-- 预览,需隐藏上传按钮,所以对maxCount绑定动态值,有几张图片,值就设为几 -->
<u-upload
:fileList="fileList3"
name="3"
:maxCount="form3.maxCount"
:previewFullImage="true"
disabled //是否启用(显示/隐藏)组件
></u-upload>
</template>
<script>
export default {
data() {
return {
//新增
form1: {
id: 201510231859001,
name: 'name1'
},
//编辑
form2: {
id: 201510231859002,
name: 'name2'
},
//预览
form3: {
id: 201510231859003,
name: 'name3',
maxCount: 0
},
fileList1: [], //新增
fileList2: [], //编辑
fileList3: [], //预览
}
},
methods:{
// 查询数据
initRender() {
uni.showLoading({
title: "数据加载中",
mask: true
})
this.$axios({
url: this.$url + "query.api",
method: 'post',
params: {
parameter1,
parameter2
}
}).then(res => {
if(res.data.success === this.$succ){
let data = res.data.data[0]
// 其它业务代码省略...
// isNull是项目中自定义全局判空方法 uni-app 直接使用 if(!data.photoUrl) 即可
// photoUrl字段 存储图片地址(多张之间以逗号隔开)
if (!this.isNull(data.photoUrl)){
// 路径
let tempPassportUrl = data.photoUrl.split(';')
// 仅预览时,设置maxCount的值,则upload组件不会显示上传按钮,编辑或新增时,不对其设置值
//data.maxCount = tempPassportUrl.length
//this.form3.maxCount = tempPassportUrl.length
// 迭代封装url组合成完整的url
for(var i = 0; i < tempPassportUrl.length; i++){
let url = tempPassportUrl[i]
// 获取name
let splitArray = url.split('/')
let name = splitArray[splitArray.length - 1]
// 存储图片路径
// 仅新增时,无需从后端查询数据,初始化时不需要往fileList1中存值
//this.fileList1 ×
// 编辑时,需从后端查询数据,url中存储文件服务器地址+存储地址,saveUrl放存储地址即可,用于保存数据
this.fileList2.push({name: name,
url: this.$ftpUrl + url,
saveUrl: url})
// 预览则不需要进行保存操作,也无需saveUrl属性
/*this.fileList3.push({name: name,
url: this.$ftpUrl + url})*/
}
}
//this.form1 ×
this.form2 = data
//this.form3 = data
uni.hideLoading()
}else{
uni.showToast({
title: res.data.message || "数据加载失败",
icon: "none"
})
}
})
},
// 删除图片
deletePic(event) {
this[`fileList${event.name}`].splice(event.index, 1)
},
// 新增图片
async afterRead(event) {
// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this[`fileList${event.name}`].length
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
//使用uni.uploadFile上传图片,后端接口返回图片保存地址
//例: /fileservice/passport/img/1656502865037.jpg
const result = await this.uploadFilePromise(lists[i].url)
let item = this[`fileList${event.name}`][fileListLen]
this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result, //这里要将完整地址 赋值给url
saveUrl: result //此处与官网略有不同,在当前页需要同时完成预览和编辑功能时,需要用到
}))
fileListLen++
}
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: this.$url + "uploadFiles.api", //仅为示例,记得修改
filePath: url,
name: 'file',
formData: { //传其它参数
user: 'test'
},
success: (res) => {
//如果后端接口返回数据是text格式,则需要JSON格式转换
//let result = JSON.parse(res.data)
setTimeout(() => {
//result.data 为图片地址
//resolve(result.data)
resolve(res.data.data)
}, 1000)
}
});
})
},
}
}
</script>
预览PDF / 图片
当“photoUrl”同时保存PDF文件地址或图片地址时
需要预览PDF,要对后端返回的数据进行判断(此处没有预览PDF相关的代码,需要的话可以留言,实现方式有点low哈,可以交流一下)
//pdf和图片只能有一种,图片可多张,pdf文件仅可上传一个
if (!this.isNull(data.photoUrl)){
//判断是jpg还是pdf
var isPDF = false
//路径
let tempPassportUrl = data.photoUrl.split(';')
if(tempPassportUrl[0].split(".")[1] == 'PDF' || tempPassportUrl[0].split(".")[1] == 'pdf'){
isPDF = true
data.maxCount = 0
} else {
data.maxCount = tempPassportUrl.length
}
//迭代封装url组合成完整的url
for(var i = 0; i < tempPassportUrl.length; i++){
let url = tempPassportUrl[i]
//获取name
let splitArray = url.split('/')
let name = splitArray[splitArray.length - 1]
if(isPDF){
this.pdfName = name
this.pdfUrl = this.$ftpUrl+url
}else{
this.fileList1.push({name: name,
url: this.$ftpUrl+url,
saveUrl: url})
}
}
}
后端接口部分代码 Java
这里没有贴完整代码哈,公司实现方式不一样,所以不一定用得到,看一下后端参数类型就行了
/**
* 上传文件
* Rest 自定义接口返回结果实体
*/
@PostMapping("/uploadFiles.api")
@ApiIgnore
public Rest uploadFiles(final MultipartFile file){
Rest rest = new Rest();
try{
String path = "/fileservice/passport/img/";
String fileUrl = file.getOriginalFilename();
//拼接文件名:时间戳+文件后缀名
fileUrl = System.currentTimeMillis() + fileUrl.substring(fileUrl.lastIndexOf("."));
//FTPUtils 自定义文件上传工具类
boolean isOk = FTPUtils.uploadFile(path, fileUrl, file);
if(isOk){
rest.setData(path + fileUrl);
}else{
rest.setSuccess(false);
rest.setMessage("上传文件失败");
rest.setErrCode("0001");
}
}catch (Exception e){
rest.setSuccess(false);
rest.setMessage(e.getMessage());
return rest;
}
return rest;
}
以下是本文全部内容,感谢查看!
欢迎参考,感谢指正!
本文含有隐藏内容,请 开通VIP 后查看