<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"。这样应该能解决你的问题!