前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Vue 文件批量下载组件封装完整使用方法与优化方案解析

Vue 文件批量下载组件封装完整使用方法与优化方案解析

原创
作者头像
小焱
发布于 2025-06-05 01:28:26
发布于 2025-06-05 01:28:26
12900
代码可运行
举报
文章被收录于专栏:前端开发前端开发
运行总次数:0
代码可运行

下面我将基于上文的技术方案,提供详细的使用方法和组件封装方案。

一、批量下载功能使用方法

(一)方案一:前端打包方案(file-saver + jszip)
  1. 安装依赖
代码语言:bash
AI代码解释
复制
npm install file-saver jszip
  1. 创建工具函数 在项目中创建utils/batchDownload.js文件:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { saveAs } from 'file-saver';
import JSZip from 'jszip';

/**
 * 批量下载文件并打包为ZIP
 * @param {Array} fileList - 文件列表,每个元素包含url和name属性
 * @param {String} zipName - 可选,ZIP文件名称
 */
export const batchDownload = async (fileList, zipName = '批量下载.zip') => {
  if (!fileList || fileList.length === 0) {
    alert('请选择要下载的文件');
    return;
  }

  const zip = new JSZip();
  const failedFiles = [];

  // 逐个下载文件并添加到ZIP
  for (const file of fileList) {
    try {
      const response = await fetch(file.url);
      if (!response.ok) throw new Error(`下载失败: ${response.statusText}`);
      
      const blob = await response.blob();
      const fileName = file.name || file.url.split('/').pop();
      zip.file(fileName, blob);
    } catch (error) {
      console.error(`文件 ${file.name || file.url} 下载失败:`, error);
      failedFiles.push(file.name || file.url);
    }
  }

  // 生成并下载ZIP文件
  const content = await zip.generateAsync({ type: 'blob' });
  saveAs(content, zipName);

  // 提示下载失败的文件
  if (failedFiles.length > 0) {
    alert(`以下文件下载失败:\n${failedFiles.join('\n')}`);
  }
};
  1. 在组件中使用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { batchDownload } from '@/utils/batchDownload';

export default {
  data() {
    return {
      selectedFiles: [
        { url: 'https://example.com/file1.pdf', name: '文档1.pdf' },
        { url: 'https://example.com/file2.jpg', name: '图片2.jpg' }
      ]
    };
  },
  methods: {
    async handleBatchDownload() {
      await batchDownload(this.selectedFiles, '资料合集.zip');
    }
  }
};
(二)方案二:后端打包方案
  1. 前端调用示例
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import axios from 'axios';

export default {
  methods: {
    async batchDownloadByBackend() {
      const fileIds = this.selectedFiles.map(file => file.id);
      
      try {
        const response = await axios.post('/api/downloadBatch', { fileIds }, {
          responseType: 'blob'
        });
        
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', '批量下载.zip');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      } catch (error) {
        console.error('下载失败', error);
        this.$message.error('批量下载失败,请稍后重试');
      }
    }
  }
};
  1. 后端接口要求
  2. 接收文件ID列表
  3. 返回ZIP文件流
  4. 设置正确的Content-Type和Content-Disposition头

二、组件封装方案

(一)通用批量下载组件

下面是一个基于方案一的可复用组件实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div class="batch-download">
    <el-button 
      :loading="isLoading" 
      @click="handleDownload"
      :disabled="selectedFiles.length === 0"
    >
      <i class="el-icon-download"></i> 批量下载
      <span v-if="selectedFiles.length > 0" class="file-count">({{selectedFiles.length}})</span>
    </el-button>
    
    <el-progress 
      v-if="isLoading && progress > 0" 
      :percentage="progress" 
      :color="progressColor"
      status="active"
    ></el-progress>
    
    <el-alert 
      v-if="failedFiles.length > 0" 
      title="部分文件下载失败" 
      type="warning"
      :description="failedFiles.join('、')"
      show-icon
    ></el-alert>
  </div>
</template>

<script>
import { batchDownload } from '@/utils/batchDownload';

export default {
  name: 'BatchDownload',
  props: {
    // 待下载的文件列表
    files: {
      type: Array,
      default: () => []
    },
    // 已选择的文件ID列表
    selectedFileIds: {
      type: Array,
      default: () => []
    },
    // ZIP文件名
    zipName: {
      type: String,
      default: '批量下载.zip'
    }
  },
  data() {
    return {
      isLoading: false,
      progress: 0,
      failedFiles: [],
      timer: null
    };
  },
  computed: {
    // 当前选中的文件
    selectedFiles() {
      if (!this.selectedFileIds || this.selectedFileIds.length === 0) {
        return this.files;
      }
      return this.files.filter(file => this.selectedFileIds.includes(file.id));
    },
    // 进度条颜色
    progressColor() {
      if (this.progress < 50) return '#20a0ff';
      if (this.progress < 80) return '#ff9900';
      return '#67c23a';
    }
  },
  methods: {
    async handleDownload() {
      if (this.selectedFiles.length === 0) {
        this.$message.warning('请选择要下载的文件');
        return;
      }
      
      this.isLoading = true;
      this.progress = 0;
      this.failedFiles = [];
      
      // 模拟进度条
      this.timer = setInterval(() => {
        if (this.progress < 90) {
          this.progress += Math.random() * 10;
        }
      }, 300);
      
      try {
        await batchDownload(this.selectedFiles, this.zipName);
        this.$message.success('下载任务已启动');
      } catch (error) {
        console.error('批量下载出错:', error);
        this.$message.error('批量下载失败,请稍后重试');
      } finally {
        this.isLoading = false;
        this.progress = 100;
        clearInterval(this.timer);
        
        // 发送下载完成事件
        this.$emit('download-complete', {
          total: this.selectedFiles.length,
          failed: this.failedFiles.length
        });
      }
    }
  },
  beforeDestroy() {
    clearInterval(this.timer);
  }
};
</script>

<style scoped>
.batch-download {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.file-count {
  margin-left: 5px;
  font-size: 12px;
  color: #606266;
}
</style>
(二)组件使用示例
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div class="file-management">
    <el-table 
      :data="fileList" 
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column label="文件名" prop="name"></el-table-column>
      <el-table-column label="大小" prop="size"></el-table-column>
      <el-table-column label="操作" width="120">
        <template #default="scope">
          <el-button 
            size="mini" 
            @click="downloadSingleFile(scope.row)"
          >
            下载
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <BatchDownload 
      :files="fileList" 
      :selectedFileIds="selectedIds"
      zipName="项目资料.zip"
      @download-complete="handleDownloadComplete"
    />
  </div>
</template>

<script>
import BatchDownload from '@/components/BatchDownload.vue';

export default {
  components: { BatchDownload },
  data() {
    return {
      fileList: [],
      selectedIds: []
    };
  },
  methods: {
    handleSelectionChange(selection) {
      this.selectedIds = selection.map(item => item.id);
    },
    handleDownloadComplete(result) {
      console.log('下载完成统计:', result);
    },
    downloadSingleFile(file) {
      // 单文件下载逻辑
    }
  }
};
</script>

三、高级功能扩展

(一)添加下载进度监控

对于大文件或大量文件的下载,可以使用fetchReadableStreamAPI监控下载进度:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 在batchDownload函数中添加进度监控
const response = await fetch(file.url);
const reader = response.body.getReader();
const contentLength = response.headers.get('Content-Length');
let receivedLength = 0;
const chunks = [];

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  
  chunks.push(value);
  receivedLength += value.length;
  
  // 更新进度
  const percent = Math.round((receivedLength / contentLength) * 100);
  this.$emit('download-progress', { file, percent });
}

const blob = new Blob(chunks);
(二)支持断点续传

对于特别大的文件,可以结合后端实现断点续传功能:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 带断点续传的下载函数
async downloadFileWithResume(url, fileName) {
  const chunkSize = 1024 * 1024; // 1MB
  let downloadedBytes = 0;
  
  // 检查是否有已下载的部分
  const storedProgress = localStorage.getItem(`download_progress_${fileName}`);
  if (storedProgress) {
    downloadedBytes = parseInt(storedProgress);
  }
  
  const response = await fetch(url, {
    headers: { Range: `bytes=${downloadedBytes}-` }
  });
  
  const totalBytes = parseInt(response.headers.get('Content-Length')) + downloadedBytes;
  const reader = response.body.getReader();
  const writer = fs.createWriteStream(fileName, { flags: 'a' });
  
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    writer.write(value);
    downloadedBytes += value.length;
    
    // 保存下载进度
    localStorage.setItem(`download_progress_${fileName}`, downloadedBytes);
    
    // 更新进度条
    const percent = Math.round((downloadedBytes / totalBytes) * 100);
    this.$emit('download-progress', { fileName, percent });
  }
  
  // 下载完成,清除进度记录
  localStorage.removeItem(`download_progress_${fileName}`);
}

四、注意事项

  1. 跨域问题
    • 如果下载的文件来自第三方域名,需要确保对方服务器设置了正确的CORS头
    • 或者通过自己的后端服务器转发请求
  2. 性能考虑
    • 前端打包方案适合小文件批量下载(总大小建议不超过100MB)
    • 大文件或大量文件建议使用后端打包方案
  3. 用户体验优化
    • 添加下载进度提示
    • 提供下载失败的文件列表
    • 支持取消下载功能

通过以上封装和使用方法,你可以在Vue项目中快速集成批量下载功能,并根据实际需求进行定制扩展。


Vue, 文件批量下载,组件封装,使用方法,优化方案,前端开发,JavaScript,Web 开发,组件化开发,代码优化,批量操作,下载功能,前端组件,Vue 组件,热门技术



资源地址:

https://pan.quark.cn/s/2d75d693deb4


原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
围绕中性粒细胞,生信能做什么
上周我们提到NETs相关的基因集,很多生信文章围绕它们做了预后分析。但NETs毕竟只是中性粒的表型之一,围绕中性粒细胞,还有没有其他东西可做呢?
生信菜鸟团
2025/02/18
1450
围绕中性粒细胞,生信能做什么
单细胞测序技术如何领跑肿瘤的免疫治疗?
歌德曾说过,“一棵树上很难找到两片叶子形状完全一样”,同样的,每一个肿瘤细胞也具有各自的特征。肿瘤是恶性肿瘤细胞、免疫细胞和间质细胞的复杂混合物,通常具有较高程度的瘤内和瘤间异质性。肿瘤微环境(TME)由促肿瘤和抗肿瘤信号组成,能够调节肿瘤生长并影响肿瘤进化。
生信交流平台
2022/09/21
7920
单细胞测序技术如何领跑肿瘤的免疫治疗?
bd平台的单细胞转录组一定能捕获到中性粒细胞吗
既然这个捕获中性粒细胞是BD单细胞转录组的卖点,那么是不是只要是选择了这个技术就一定能能捕获到中性粒细胞呢?让我们随机看看其它比较新的文章,比如同样的2023的《Single-cell and spatial transcriptome analysis reveals the cellular heterogeneity of liver metastatic colorectal cancer》,数据 是 196,473 CD45+ immune cells from 27 samples of six CRC patients, 链接在;https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE225857
生信技能树
2023/11/13
5210
bd平台的单细胞转录组一定能捕获到中性粒细胞吗
生信数据分析可靠与否是一个伪命题
最简单的一个生物信息学数据分析案例,可以是针对一个表达量矩阵以及里面的样品分组进行差异分析,然后拿到统计学显著的上下调基因列表,因为基因数量很多,所以我们默认会做一些生物学功能数据库注释。这里面的生物信息学算法就差异分析和注释算法, 它本身是非常可靠的!
生信技能树
2024/11/21
1120
生信数据分析可靠与否是一个伪命题
可能是作者把部分样品标记错误了分组吗
其中里面的普通转录组数据集链接是:https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE243245
生信技能树
2023/11/25
2100
可能是作者把部分样品标记错误了分组吗
爱恨难分—癌症免疫治疗获得性抗性
每个人的时间精力有限,必须优先阅读相关文献,开设这个栏目也是希望为大家推荐高质量的单细胞相关文献。如果大家对单细胞转录组感兴趣可以关注一下,哪怕每天只学一点点,积土成山,积水成渊。
生信技能树jimmy
2020/03/27
1K0
生信爱好者周刊(第 1 期):生信是什么
讨论区的帖子《谁在招人?》[2],提供生信深造和就业信息,欢迎访问或发布学位攻读/工作/实习等岗位。
王诗翔呀
2022/01/21
9630
生信爱好者周刊(第 1 期):生信是什么
癌症免疫研究的技术进步:从免疫基因组学到单细胞分析和人工智能
肿瘤细胞与附近的细胞一起存在于复杂的细胞群落中,这强烈影响肿瘤细胞的生长、行为和与其他细胞的交流。在这些细胞中,免疫细胞是关键的参与者,许多研究证明肿瘤细胞和免疫细胞之间的交流是双向的。事实上,免疫细胞既能促进也能抑制癌变、肿瘤进展、转移和复发。因此,文章主要关注肿瘤免疫微环境(TIME)。
生信技能树jimmy
2022/03/14
1.2K0
癌症免疫研究的技术进步:从免疫基因组学到单细胞分析和人工智能
单细胞时代 || 从众病之王到希望之光
这不是最好的时代,也不是最坏的时代,这里是单细胞时代。灵活的单细胞系统,高效的组织解离液,开源的数据分析工具,端到端的单细胞解决方案是未来发展的趋势。这里最主要的是开放灵活的单细胞系统,有了这个系统我们就可以自主地设计反应体系,来从不同纬度捕获单个细胞的信息。
生信技能树jimmy
2021/03/10
6670
单细胞时代 || 从众病之王到希望之光
生信爱好者周刊(第 54 期):人类和人生的意义
本杂志开源(GitHub: ShixiangWang/weekly[1]),欢迎提交 issue,投稿或推荐生信相关内容。
王诗翔呀
2022/12/30
9190
生信爱好者周刊(第 54 期):人类和人生的意义
生信分析的本手妙手俗手
对于初学者而言,应该从本手开始,本手的功夫扎实了,棋力才会提高。一些初学者热衷于追求妙手,而忽视更为常用的本手。本手是基础,妙手是创造。一般来说,对本手理解深刻,才可能出现妙手;否则,难免下出俗手,水平也不易提升。
生信技能树
2022/07/26
7030
生信分析的本手妙手俗手
医学科研离不开临床医生啊
哪怕是一个生命科学领域的博士生,没有上过临床,对科研的想象也是有限度的,比如大家都知道可以做癌症研究,普通人能想到的实验设计是可以探索癌症的生物学特性、机制、治疗响应以及疾病进展。以下是一些常见的实验设计类型,包括但不限于:
生信技能树
2024/11/21
700
医学科研离不开临床医生啊
生信爱好者周刊(第 128 期):什么事情使你放弃了学术理想?
本杂志开源(GitHub: ShixiangWang/weekly[1]),欢迎提交 issue,投稿或推荐生信相关内容。
生信技能树
2024/07/05
1260
生信爱好者周刊(第 128 期):什么事情使你放弃了学术理想?
不要动不动就花纳税人的钱测序
作为华语界生物信息学领域中文自媒体扛把子的我看起来应该是马上就得炮轰饶毅老师的《为什么批评测序?》观点,因为目前测序基本上就等于生物信息学,所以是我们的生信工程师的生命线。而且这个冲突就是纯粹的代沟,目前主流的30到40岁的生命科学领域从业者基本上是伴随着测序一步步起家的, 跟50到60岁左右的已经功成名就的科学家太不一样了。不知道大家是否还记得《亚当斯科技三定律》:
生信技能树
2024/12/10
1260
不要动不动就花纳税人的钱测序
生信爱好者周刊(第 21 期):科研与爱好
“iMeta” 是由威立、肠菌分会和本领域数百位华人科学家合作出版的开放获取期刊,主编由中科院微生物所刘双江和荷兰格罗宁根大学傅静远教授担任。目的是发表原创研究、方法和综述以促进宏基因组学、微生物组和生物信息学发展。目标是发表前10%(IF>15)的高影响力论文。期刊特色包括视频投稿、可重复分析、图片打磨、青年编委、前3年免出版费、50万用户的社交媒体宣传等。第一期于2022年2月正式发布。
王诗翔呀
2022/03/30
4070
生信爱好者周刊(第 21 期):科研与爱好
生信爱好者周刊(第 29 期):Hiplot开发库开源
Hiplot 项目发起于 2019 年,是由国内生物信息学开源社区 Openbiox 和多家单位和机构共同建设的一个免费、易用、部分开源的综合在线绘图系统(生物医学为主)。截至目前,该网站已提供超过 230+余个在线可视化分析功能,涵盖了基础科研绘图、组学可视化和部分临床模型可视化功能。总的注册用户已超过 2 万 5 千人,总访问量超过 300 万次,每日任务数已超 4000 余次。
王诗翔呀
2022/06/27
6180
生信爱好者周刊(第 29 期):Hiplot开发库开源
细胞免疫疗法TCR-T和空间VDJ测序
人类肿瘤抗原主要可分为两类——肿瘤特异性抗原(例如,新抗原和病毒抗原)和肿瘤相关抗原(例如,癌症/睾丸(CT)抗原、过表达抗原和分化抗原)。尽管TCR-T细胞可以靶向所有肿瘤抗原,但迄今为止确定的具有足够安全性和有效性的靶点数量仍然有限。选择合适的TCR-T细胞治疗靶抗原的首要考虑应该是抗原的高特异性。通常选择在肿瘤中高表达但在正常组织中低水平表达的靶抗原来限制任何潜在的脱靶效应和由破坏表达靶抗原的正常组织引起的剂量限制毒性。迄今为止,大多数TCR-T细胞疗法的临床试验都针对CT抗原和病毒抗原,其中纽约食管鳞状细胞癌1(NY-ESO-1)是最常针对的,占迄今为止试验的37%。
追风少年i
2024/02/18
2530
细胞免疫疗法TCR-T和空间VDJ测序
纯粹靠单细胞转录组数据是很难区分CD4和CD8阳性T细胞
我这里就不摘抄代码给大家了,官方文档很详细,https://satijalab.org/seurat/articles/pbmc3k_tutorial.html ,内容很简单而且步骤很清晰:
生信技能树
2023/11/23
2.3K0
纯粹靠单细胞转录组数据是很难区分CD4和CD8阳性T细胞
临床生物信息学工作者需要哪些【硬技能】和【软技能】?
生信菜鸟团
2025/01/02
1710
临床生物信息学工作者需要哪些【硬技能】和【软技能】?
PDX小鼠模型的单细胞样品定量能选择人类参考基因组吗
其中肿瘤病人的多组学数据(肿瘤外显子以及转录组)目前管理很严格,所以是没办法公开获取的,但是文献里面的The single-cell RNA sequencing data of 6 PDX mice 是可以公开的:https://ngdc.cncb.ac.cn/gsa/browse/CRA010501 ,确实是可以看到这个PDX小鼠模型的单细胞样品定量是选择的人类参考基因组:
生信技能树
2024/11/21
1160
PDX小鼠模型的单细胞样品定量能选择人类参考基因组吗
推荐阅读
相关推荐
围绕中性粒细胞,生信能做什么
更多 >
LV.1
澳门大学在读博士
目录
  • 一、批量下载功能使用方法
    • (一)方案一:前端打包方案(file-saver + jszip)
    • (二)方案二:后端打包方案
  • 二、组件封装方案
    • (一)通用批量下载组件
    • (二)组件使用示例
  • 三、高级功能扩展
    • (一)添加下载进度监控
    • (二)支持断点续传
  • 四、注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档