项目要求:需要下载线上的文件,如果用<a href=".../1.jpg" download></a>,直接打开图片,不会将文件下载到本地,只能用以下方法解决
- download.js
/* 下载 */
export function downloadFiles(filePath, fileName) {
fetch(filePath).then(res => res.blob()).then(blob => {
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = fileName;
document.body.appendChild(a); //追加a标签
a.click(); //a标签点击
document.body.removeChild(a); //移除节点
})
}
- 在具体页面调用 下载JS
<!-- 预览文件(包括图片、文档等) -->
<template>
<div class="attPreview flexColumn">
<!-- 头部 -->
<div class="previewHeader">
<div class="flexRow">
<div class="editableBlock editName" :title="fileInfo.FIName">
<span class="content">
<span class="fileName ellipsis" style="min-width:8px;">{{ fileInfo.FIName }}</span>
</span>
</div>
<div class="flex"></div>
<a class="comm-preA InlineBlock Hand preDoc_download" title="下载" @click="clickDownload(fileInfo)">
<vab-icon icon="download-fill" />
</a>
<div class="attClose Hand" title="关闭" @click="closeAttPreview">
<vab-icon icon="close-fill" />
</div>
</div>
</div>
<!-- 内容 -->
<div class="previewPanel">
<div class="previewContainer">
<!-- 图片 -->
<div class="dragAbleContainer fileViewer imageViewer"
v-if="currentExt=='png' || currentExt=='gif' || currentExt=='bmp' || currentExt=='jpg' || currentExt=='jpeg'">
<img class="dragAbleImg noSelect grab" id="gvh_imgsrc" :src="fileInfo.FFilePath" />
</div>
<!-- 文档 -->
<div class="ifContainer"
v-else-if="currentExt=='pptx' || currentExt=='ppt' || currentExt=='pot' || currentExt=='potx' || currentExt=='pps' || currentExt=='ppsx' || currentExt=='dps' || currentExt=='dpt' || currentExt=='pptm' || currentExt=='potm' || currentExt=='ppsm' || currentExt=='xls' || currentExt=='xlt' || currentExt=='et' || currentExt=='ett' || currentExt=='xlsx' || currentExt=='xltx' || currentExt=='csv' || currentExt=='xlsb' || currentExt=='xlsm' || currentExt=='xltm' || currentExt=='doc' || currentExt=='dot' || currentExt=='wps' || currentExt=='wpt' || currentExt=='docx' || currentExt=='dotx' || currentExt=='docm' || currentExt=='dotm' || currentExt=='lrc' || currentExt=='c' || currentExt=='cpp' || currentExt=='cmd' || currentExt=='rtf' || currentExt=='txt' || currentExt=='log' || currentExt=='xml' || currentExt=='htm' || currentExt=='html' || currentExt=='pdf'">
<iframe id="preDocContent" width="100%" height="100%"
:src="fileInfo.FFilePath+'#scrollbars=0&toolbar=0&statusbar=0'" type="application/pdf"
style="border:none;"></iframe>
</div>
<!-- 视频 -->
<!-- 其它 -->
<div class="canNotView"
v-else-if="currentExt=='wmv' || currentExt=='asf' || currentExt=='asx' || currentExt=='rm' || currentExt=='rmvb' || currentExt=='mp3' || currentExt=='mp4' || currentExt=='mpg' || currentExt=='mpeg' || currentExt=='3gp' || currentExt=='mov' || currentExt=='m4v' || currentExt=='avi' || currentExt=='dat' || currentExt=='mkv' || currentExt=='flv' || currentExt=='vob'">
<attIcon :ext="currentExt"></attIcon>
<p class="fileName">{{ fileInfo.FIName }}</p>
<a class="btn btn-primary downloadBtn" @click="clickDownload(fileInfo)">下载</a>
</div>
</div>
</div>
<!-- 底部 -->
<div class="thumbnailGuide"
v-if="currentExt=='png' || currentExt=='gif' || currentExt=='bmp' || currentExt=='jpg' || currentExt=='jpeg'">
<div class="statusBar fle">
<div class="fold">
<div class="InlineBlock">
<div class="iOperate Hand">
<vab-icon icon="zoom-in-line" title="放大" @click="enlargeImg" />
<vab-icon icon="zoom-out-line" title="缩小" @click="narrowImg" />
<el-icon class="io_refresh" title="旋转" @click="rotateImg">
<refresh-left />
</el-icon>
<a class="originImage Hand noSelect" :href="fileInfo.FFilePath" target="_blank" title="查看图片">原图</a>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { defineComponent, defineAsyncComponent, onMounted, reactive, toRefs } from 'vue'
import { getFilesInfo } from '../../../api/file.js'
import { downloadFiles } from "@/utils/download.js";
export default {
name: 'PreviewFiles',
components: {
attIcon: defineAsyncComponent(() => import('../../components/att/index.vue'))
},
props: {
id: {
type: String,
default: ''
},
ext: {
type: String,
default: ''
}
},
emits: ['close'],
setup(props, { emit }) {
//////////////////////////////////////////////////////////////////////////////////////////1、定义变量
const state = reactive({
fileInfo: [], //文件详情
currentID: props.id,
currentExt: props.ext
})
//////////////////////////////////////////////////////////////////////////////////////////2、关闭
const closeAttPreview = () => {
emit("close", 0)
}
//////////////////////////////////////////////////////////////////////////////////////////3、获取文件详情
const fetchData = async () => {
var resultData = await getFilesInfo({
'token': localStorage.getItem('access_token'),
"l_i": state.currentID,
"f_t": state.currentExt
})
if (resultData["code"] == 200) {
state.fileInfo = resultData["data"][0]
} else {
state.fileInfo = []
}
}
onMounted(() => {
fetchData()
})
//////////////////////////////////////////////////////////////////////////////////////////4、下载
const clickDownload = (fileInfo) => {
downloadFiles(fileInfo.FFilePath, fileInfo.FIName);
}
//////////////////////////////////////////////////////////////////////////////////////////5、放大图片
const enlargeImg = () => {
var oImg = document.getElementById("gvh_imgsrc");
oImg.style.width = (oImg.width * 1.2) + "px";
oImg.style.height = (oImg.height * 1.2) + "px";
}
//////////////////////////////////////////////////////////////////////////////////////////6、缩小图片
const narrowImg = () => {
var oImg = document.getElementById("gvh_imgsrc");
var widthImg = oImg.width / 1.2;
var heightImg = oImg.height / 1.2;
if (widthImg > 250) {
oImg.style.width = widthImg + "px";
oImg.style.height = heightImg + "px";
}
}
//////////////////////////////////////////////////////////////////////////////////////////7、旋转图片
var current = 0;
const rotateImg = () => {
current = (current + 90) % 360;
var oImg = document.getElementById("gvh_imgsrc");
oImg.style.transform = 'rotate(' + current + 'deg)';
}
return {
...toRefs(state),
closeAttPreview,
clickDownload,
enlargeImg,
narrowImg,
rotateImg
}
}
}
</script>
<style>
</style>
- 效果图