<template>
<el-dialog v-model="downExcel.downExcelDialog" title="下载成功" width="300">
<a
style="color: #409eff"
:href="downExcel.href"
:download="downExcel.fileName"
target="_blank"
ref="downloadLink"
>
{{ downExcel.fileName }}
</a>
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
const downExcel = reactive({
downExcelDialog: false,
href: "",
fileName: "",
});
const downloadLink = ref();
defineExpose({
openDialog,
});
function openDialog(fileData, fileName) {
const blob = new Blob([fileData], {
type: "application/octet-stream",
});
var href = window.URL.createObjectURL(blob); // 创建下载的链接
downloadLink.value = href;
downExcel.href = href;
downExcel.fileName = fileName;
downExcel.downExcelDialog = true;
}
</script>
a标签点击不会打开新的页面下载文件,已经设置了 target="_blank"
在你的代码中,<a>
标签设置了 target="_blank"
,但仍然没有在新页面下载文件,可能是因为 浏览器阻止了弹窗,或者 href
的生成方式有问题。以下是解决方案:
window.URL.createObjectURL()
生成的链接在新窗口打开(视为不安全弹窗)。<a>
标签。href
生成后未立即触发下载downExcel.downExcelDialog = true
显示弹窗后,浏览器可能不会自动处理下载。openDialog
方法中,手动触发 <a>
的点击事件。<template>
<el-dialog v-model="downExcel.downExcelDialog" title="下载成功" width="300">
<a
style="color: #409eff"
:href="downExcel.href"
:download="downExcel.fileName"
ref="downloadLink"
>
{{ downExcel.fileName }}
</a>
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive, ref, nextTick } from "vue";
const downExcel = reactive({
downExcelDialog: false,
href: "",
fileName: "",
});
const downloadLink = ref<HTMLAnchorElement>(); // 明确类型
function openDialog(fileData: BlobPart, fileName: string) {
const blob = new Blob([fileData], {
type: "application/octet-stream",
});
const href = window.URL.createObjectURL(blob);
downExcel.href = href;
downExcel.fileName = fileName;
downExcel.downExcelDialog = true;
// 等待弹窗渲染完成后,自动触发下载
nextTick(() => {
if (downloadLink.value) {
downloadLink.value.click(); // 手动触发点击
window.URL.revokeObjectURL(href); // 释放内存(可选)
downExcel.downExcelDialog = false; // 关闭弹窗(可选)
}
});
}
defineExpose({ openDialog });
</script>
移除 target="_blank"
手动触发 <a>
点击
nextTick
确保 DOM 更新后,再通过 downloadLink.value.click()
触发下载。释放内存(可选)
window.URL.revokeObjectURL(href)
可以释放 Blob
占用的内存,但如果在下载前调用会导致链接失效,所以建议在下载完成后执行(例如在 setTimeout
中延迟调用)。如果浏览器仍然阻止下载,可以改用 FileSaver.js
(一个专门处理文件下载的库):
npm install file-saver
然后修改代码:
import { saveAs } from "file-saver";
function openDialog(fileData: BlobPart, fileName: string) {
const blob = new Blob([fileData], { type: "application/octet-stream" });
saveAs(blob, fileName); // 直接下载,无需 <a> 标签
downExcel.downExcelDialog = true; // 仅显示提示(可选)
}
<a>
点击(如修改后的代码)。FileSaver.js
直接下载。Blob
链接的弹窗,因此避免依赖 target="_blank"
。这样应该能解决你的问题!