性能要求:上传文件后点击已上传的文件,实现图片格式与pdf格局的文件关上预览文档格局的文件点击下载并且下载时候的文件名与上传时保持一致。
问题:
因为后盾为了解决可能呈现的雷同文件名上传而导致后传的文件笼罩上一次文件的状况,就在文件上传至服务器后在文件名前面加一串随机串。这样导致在接口返回给前端的url的地址上会变成 文件名+随机字符串 。同时,这样就导致前端也呈现一个状况:如果间接用a-upload组件封装的点击事件进行文件下载,下载后的文件名后会有一串随机字符串。这样就不合乎需要要求的保障下载时的文件名称与上传统一,为此,就须要自定义一下a-upload的点击下载事件。
景象:
呈现起因:
a-upload组件在上传了文件后,主动生成了a标签,点击文件时触发a标签的下载事件。如图
解决:
<div class="divBox" v-for="(item, index) uploadList" :key="item.title"> <span v-if="item.title" class="divBox-title">{{ item.title }}:</span> <a-upload v-model:file-list="item.fileList" :customRequest="customRequest" :beforeUpload="beforeUpload" :accept="item.accept" @preview="previewFile" > <a-button :loading="item.loading" :disabled="item.loading"> Upload </a-button> </a-upload></div>
const uploadList = ref([]) // 文件数组const fIndex = ref() // 以后上传数据索引// 上传const customRequest = file => { const api = uploadList[fIndex.value].api const maxNum = uploadList[fIndex.value].maxNum const formData = new FormData() formData.append('file', file.file) // 去除后缀指定文件名 formData.append('fileName', file.file.name.substring(0, file.file.name.lastIndexOf('.'))) // 获取以后文件上传前文件数量 const listNum = uploadList[fIndex.value].fileList.length request .post(url, formData) .then(res => { if (res.result == 0) { // 上传胜利贮存url uploadList[fIndex.value].fileList[uploadList[fIndex.value].fileList.length - 1].url = res.data.url const params = { url: res.data.url } request.post(api, params).then(result => { if (result.result == 0) { file.onSuccess(res, file.file) // 上传胜利判断是否超出文件数量 if (listNum >= maxNum) { // 超出文件数量删除第一项文件 uploadList[fIndex.value].fileList.shift() } } else { message.error(result.message) uploadList[fIndex.value].fileList.splice(listNum, 1) } uploadList[fIndex.value].loading = false }) .catch(() => { uploadList[fIndex.value].loading = false }) .finally(() => { // 申请完结更改为完结状态 uploadList[fIndex.value].loading = false }) } else { uploadList[fIndex.value].fileList.splice(listNum, 1) } }) .catch(() => { // 上传失败 uploadList[fIndex.value].fileList.splice(listNum, 1) })}// 上传前事件const beforeUpload = (file, fileList) => { const size = uploadList[fIndex.value].size const maxNum = uploadList[fIndex.value].maxNum const fileLists = uploadList[fIndex.value].fileList const isVerify = uploadList[fIndex.value].isVerify const accept = uploadList[fIndex.value].accept const isLt = file.size / 1024 / 1024 < size // 校验文件格局 let type = false accept.split(',').forEach(e => { const filetype = file.name.split('.')[file.name.split('.').length - 1] if ('.' + filetype == e) { type = true } }) if (!type) { message.error('文件格式谬误,请从新上传') fileList.pop() return false } else { // 校验文件数量 if (fileLists.length < maxNum) { // 校验文件大小 if (!isLt) { message.error('文件大小超出' + size + 'M,请批改后从新抉择文件') fileList.pop() return false } else { return true } } else { if (isVerify) { return true } else { message.error('上传数量不能超过' + maxNum + '个') fileList.pop() return false } } }}// 自定义的下载和预览办法const previewFile = item => { // 依据文件的后缀进行预览或是下载操作 if (item.name.endsWith('.jpg') || item.name.endsWith('.png')) { const imgWindow = window.open('') imgWindow && imgWindow.document.write(`<image src='${item.url}' style='display: flex; margin: 0 auto'/>`) } else if (item.name.endsWith('.pdf')) { window.open(item.url + '?response-content-type=application/pdf') } else { if (item.url) { downloadFile(item.url, item.name) } }}// 下载文件 将后盾返回的文件url链接转换为文件流格局,点击关上新窗口下载文件const downloadFile = async (url, fileName = null) => { const a = document.createElement('a') // 创立a标签 if (fileName) { const response = await fetch(url) // 内容转变成blob地址 const blob = await response.blob() // 创立暗藏的可下载链接 const objectUrl = window.URL.createObjectURL(blob) a.href = objectUrl a.download = fileName } else { a.href = url } a.click() a.remove()}
这样就能够将文件依照需要要求进行下载和预览