背景
项目需要多张图片上传回显,图片上传后返回图片ID,不返回url,需要通过图片ID获取token然后再拼接成图片下载的URL。选择el-upload组件进行开发。
- file-list:文件列表,上传下载都需要手动维护该变量,{url:‘xxx’, fileId: ‘111’},url为必选字段用来显示图片。
- action:默认的图片上传地址(必传),这里需要重新定义上传逻辑因此设置为#。
- http-request:定义上传逻辑,入参没有使用到(本以为入参中为会待上传的文件,但是实际没有),文件上传完成之后,需要把文件追加到file-list变量中()。
- on-change:文件状态变更回调,入参为变化的文件和文件列表。因为前面http-request的入参中没有待上传文件,需要在这里待上传文件保存到变量。
- on-remove:文件删除回调,入参为已删除的文件和文件列表,这里需要将已删除文件从file-list变量中删除,这里通过fileId进行查找并删除。
代码
<!-- 图片上传组件,回显不生效时需要手动调用refresh渲染 -->
<template>
<div>
<el-upload action="#"
list-type="picture-card" :on-preview="handlePictureCardPreview"
:on-change="fileChange"
:on-remove="handleRemove"
:on-error="uploadError"
:http-request="fileUpload"
:file-list="initFileIds"
:disabled="disabled"
>
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
import { uploadFile, getObsToken } from '@/api/obs'
import system from '@/models/system'
import base from '@/api/base'
export default {
props: ['initFileIds', 'disabled'],
data() {
return {
dialogImageUrl: '',
dialogVisible: false,
fileIds: '',
file: {}
}
},
computed: {
fileIdList () {
return this.initFileIds.map(item => item.fileId)
}
},
methods: {
fileChange(file, files) {
this.file = file
},
async fileUpload(uploadData) {
const formData = new FormData()
formData.append('file', this.file.raw)
formData.append('fileName', this.file.name)
const data = await uploadFile(formData)
if (data && data[system.codeParam] === system.okCode) {
const fileId = data.commonInfo.fileId
getObsToken({
fileId: fileId
}).then(res => {
if (res && res[system.codeParam] === system.okCode) {
this.initFileIds.push({
uid: this.file.uid,
fileId: fileId,
url: `${base.url}/downloadFileByToken/${fileId}/${res.commonInfo.downloadToken}`
})
}
})
} else {
throw Error()
}
},
uploadError(response, file, fileList) {
console.log('uploadError', response, file, fileList)
this.$message.error('上传失败')
},
handleRemove(file, fileList) {
// 删除上传文件
let index = -1
this.initFileIds.forEach((element, i) => {
if (element.uid === file.uid || element.fileId === file.fileId) {
index = i
}
})
if (index >= 0) {
this.initFileIds.splice(index, 1)
}
},
handlePictureCardPreview(file) {
console.log('handlePictureCardPreview', file)
this.dialogImageUrl = file.url
this.dialogVisible = true
},
refresh() {
console.log('refresh upload', this.initFileIds)
if (this.initFileIds) {
this.initFileIds.forEach(item => {
if (item.url) {
return
}
getToken({
fileId: item.fileId
}).then(res => {
if (res && res[system.codeParam] === system.okCode) {
item.url = `${base.url}/downloadFileByToken/${item.fileId}/${res.commonInfo.downloadToken}`
this.$forceUpdate()
}
})
})
}
}
},
mounted() {
this.refresh()
}
}
</script>