实现功能:在移动端使用van-uploader组件上传图片,然后调用接口保存到后端数据库,提交保存信息成功后,调用另外的接口返回数据用来回显uploaded的文件,(一般正常的返回数据的接口是个图片地址,可以直接显示),我现在遇到的功能是返回了一个图片地址,然后我需要在前端页面自己去调一次图片地址的接口。
<div class="imgWrap">
<!-- :max-count="3" -->
<van-uploader
:disabled="isUpload"
:before-read="beforeUpHandle"
:after-read="onRead"
@click="emitCont"
v-model="fileList"
multiple
:max-count="15"
@delete="handleRemove"
>
<van-button
icon="photograph
"
></van-button>
<div class="addImg">添加图片</div>
</van-uploader>
</div>
对van-uploader组件不熟悉的可以去官网自行查看
保存信息的接口代码:
这里要在文件读取完成后的回调函数中使用
async function onRead(file: any, detail: any) {
let formData = new FormData() //格式化必不可少,在里面添加接口需要传的参数
formData.append('file', file.file)
formData.append('sort', detail.index)
getUploadKey(formData).then(res => {
if (res.resultCode === '00') {
let result = res.data
}
})
}
接下来是回显接口返回的数据在uploader,这里主要遇到的是v-model的fileList绑定的值,把接口获取的值直接赋值给fileList即可以。
1、获取接口的值,我这边假设为fetchData,我做了一个判断,fetchData有值才调用图片地址的数据
if (fetchData.value.length > 0) {
//当回显的图片有多张时需要做一个循环
for (let i = 0; i < fetchData.value.length; i++) {
let item =fetchData.value[i];
item = {
url: item.imgUrl, //这里的imgUrl后端接口返回的图片地址
sort: item.sort, //这里的数据按照自己的实际情况添加,我是后面需要到sort才添加的,不然有url即可显示
}),
console.log(item.url, 'uuuu')
//开始调用图片地址接口,因为我这里图片接口返回的二进制流图片数据格式,前端需要处理才能显示。如下使用的是:
1、先设置axios接收参数格式为"arraybuffer"
2、转换为base64格式图片数据在img标签显示
3、return 'data:image/png;base64,' + btoa( new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), '') );
axios({
method: 'get',
url: item.url,
headers: {
'XXX-XXX-TOKEN': XXXXXX,//需要到token的小伙伴借鉴
},
responseType: 'arraybuffer',
})
.then(res => {
//若是没有做这个obj的封装,图片将无法显示。
let obj = {
content: `data:image/png;base64,${btoa(
new Uint8Array(res.data).reduce(
(data, byte) => data + String.fromCharCode(byte),
'',
),
)}`,
sort: item.sort,
}
fileList.value.push(obj)
})
.catch(err => {
reject(err.data)
})
}
}
补充:van-uploader这个组件要回显图片两种方法:
1、提供图片的base64字符串
直接把base64字符串加前缀之后,封装成一个obj放入fileList,就可以直接回显图片
2、提供文件的二进制流
(这种能回显图片因为后端能接受这样的请求方式。但现在很多框架不支持没有完整请求头的请求,那么就会请求不到后端图片回显失败,这种方式还是有一定局限性的),我一开始用的这个方法就是没有实现回显所以又考虑转为base64格式来显示。