Vue3实现文件上传、下载及预览全流程详解(含完整接口调用)


文章目录
- 一、环境准备
- 1.1 创建Vue3项目
- 1.2 安装依赖
- 1.3 配置Element Plus
- 二、文件上传实现
- 2.1 基础上传组件
- 2.2 自定义上传逻辑(Axios实现)
- 三、文件下载实现
- 3.1 直接下载(已知文件URL)
- 3.2 后端接口下载(二进制流)
- 四、文件预览实现
- 4.1 图片预览
- 4.2 PDF预览(使用pdf.js)
- 4.3 Excel预览(使用xlsx)
- 五、完整接口示例
- 5.1 上传接口(Node.js示例)
- 5.2 下载接口(Node.js示例)
- 六、注意事项
- 七、完整项目结构
- 八、总结
一、环境准备
1.1 创建Vue3项目
npm create vue@latest
# 选择TypeScript、Pinia(可选)、ESLint等配置
1.2 安装依赖
npm install axios element-plus @element-plus/icons-vue
1.3 配置Element Plus
// main.ts
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'const app = createApp(App)
app.use(ElementPlus)
二、文件上传实现
2.1 基础上传组件
<template><el-uploadclass="upload-demo":action="uploadUrl":headers="headers":on-success="handleSuccess":before-upload="beforeUpload"><el-button type="primary">点击上传</el-button><template #tip><div class="el-upload__tip">支持扩展名:.jpg/.png/.pdf,最大5MB</div></template></el-upload>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { UploadProps } from 'element-plus'const uploadUrl = ref('https://api.example.com/upload')
const headers = ref({Authorization: 'Bearer ' + localStorage.getItem('token')
})// 文件预校验
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {const isValidType = ['image/jpeg', 'image/png', 'application/pdf'].includes(rawFile.type)const isLt5M = rawFile.size / 1024 / 1024 < 5if (!isValidType) {ElMessage.error('文件格式不支持!')return false}if (!isLt5M) {ElMessage.error('文件大小不能超过5MB!')return false}return true
}// 上传成功回调
const handleSuccess: UploadProps['onSuccess'] = (response) => {ElMessage.success('上传成功')console.log('服务器返回:', response)// 通常返回文件访问地址
}
</script>
2.2 自定义上传逻辑(Axios实现)
const customUpload = async (file: File) => {const formData = new FormData()formData.append('file', file)formData.append('userId', '123')try {const { data } = await axios.post('/api/upload', formData, {headers: {'Content-Type': 'multipart/form-data',Authorization: `Bearer ${localStorage.getItem('token')}`}})return data} catch (error) {ElMessage.error('上传失败')throw error}
}
三、文件下载实现
3.1 直接下载(已知文件URL)
<template><el-button @click="handleDownload">下载文件</el-button>
</template><script setup lang="ts">
const handleDownload = () => {const link = document.createElement('a')link.href = 'https://api.example.com/files/sample.pdf'link.download = 'filename.pdf' // 设置下载文件名document.body.appendChild(link)link.click()document.body.removeChild(link)
}
</script>
3.2 后端接口下载(二进制流)
const downloadFile = async (fileId: string) => {try {const response = await axios.get(`/api/download/${fileId}`, {responseType: 'blob'})// 创建Blob对象const blob = new Blob([response.data])const url = window.URL.createObjectURL(blob)// 提取文件名const contentDisposition = response.headers['content-disposition']const fileName = contentDisposition?.split('filename=')[1]?.replace(/"/g, '')|| 'download-file'// 创建下载链接const link = document.createElement('a')link.href = urllink.download = fileNamedocument.body.appendChild(link)link.click()window.URL.revokeObjectURL(url)document.body.removeChild(link)} catch (error) {ElMessage.error('下载失败')}
}
四、文件预览实现
4.1 图片预览
<template><el-image :src="imageUrl" :preview-src-list="[imageUrl]"fit="cover"/>
</template>
4.2 PDF预览(使用pdf.js)
npm install pdfjs-dist @types/pdfjs-dist
<template><div ref="pdfContainer" class="pdf-viewer"></div>
</template><script setup lang="ts">
import { ref, onMounted } from 'vue'
import * as pdfjsLib from 'pdfjs-dist'const props = defineProps<{pdfUrl: string
}>()const pdfContainer = ref<HTMLElement>()onMounted(async () => {const loadingTask = pdfjsLib.getDocument(props.pdfUrl)const pdf = await loadingTask.promisefor (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {const page = await pdf.getPage(pageNum)const viewport = page.getViewport({ scale: 1.5 })const canvas = document.createElement('canvas')const context = canvas.getContext('2d')!canvas.height = viewport.heightcanvas.width = viewport.widthawait page.render({canvasContext: context,viewport: viewport}).promisepdfContainer.value?.appendChild(canvas)}
})
</script>
4.3 Excel预览(使用xlsx)
npm install xlsx
<template><el-table :data="excelData"><el-table-column v-for="(col, index) in columns":key="index":prop="col":label="col"/></el-table>
</template><script setup lang="ts">
import { read, utils } from 'xlsx'
import { ref } from 'vue'const excelData = ref([])
const columns = ref([])const previewExcel = async (file: File) => {const data = await file.arrayBuffer()const workbook = read(data)const worksheet = workbook.Sheets[workbook.SheetNames[0]]const jsonData = utils.sheet_to_json(worksheet, { header: 1 })columns.value = jsonData[0]excelData.value = jsonData.slice(1).map(row => {return columns.value.reduce((obj, col, index) => {obj[col] = row[index]return obj}, {})})
}
</script>
五、完整接口示例
5.1 上传接口(Node.js示例)
// Express 路由
app.post('/api/upload', (req, res) => {const multer = require('multer')const upload = multer({ dest: 'uploads/' })upload.single('file')(req, res, (err) => {if (err) return res.status(500).json({ code: 500, message: '上传失败' })// 返回文件信息res.json({code: 200,data: {url: `/files/${req.file.filename}`,originalname: req.file.originalname,size: req.file.size}})})
})
5.2 下载接口(Node.js示例)
app.get('/api/download/:filename', (req, res) => {const filePath = path.join(__dirname, 'uploads', req.params.filename)res.setHeader('Content-Type', 'application/octet-stream')res.setHeader('Content-Disposition', `attachment; filename=${req.params.filename}`)const fileStream = fs.createReadStream(filePath)fileStream.pipe(res)
})
六、注意事项
- 安全验证:所有文件接口需进行身份验证
- 文件大小限制:Nginx需配置
client_max_body_size - 文件存储:
- 敏感文件不要存储在公开目录
- 使用OSS云存储更佳
- 预览安全:
- 防止XSS攻击(特别处理HTML文件)
- 使用CSP内容安全策略
七、完整项目结构
/src
├─api/
│ └─file.ts # 文件相关接口封装
├─components/
│ └─FilePreview.vue # 文件预览组件
├─utils/
│ ├─download.ts # 下载工具函数
│ └─validation.ts # 文件验证函数
八、总结
本文全面而详尽地实现了多项关键功能,为开发者提供了从前端到后端、从组件开发到接口对接的全方位解决方案。首先,我们基于Element Plus这一流行的Vue3组件库,成功构建了一个高效且用户友好的文件上传组件。该组件不仅支持文件的快速上传,还提供了丰富的用户交互体验,如进度条显示、上传成功/失败提示等,极大地提升了用户的使用感受。
在文件处理方面,我们实现了Axios二进制流文件的下载功能。通过Axios的强大网络请求能力,我们能够轻松地从服务器获取二进制文件流,并将其保存到本地或进行进一步的处理。这一功能为文件的异步下载和动态处理提供了有力支持。
为了满足不同格式文件的预览需求,我们精心设计了一套PDF/Excel/图片多格式的预览方案。该方案能够自动识别文件类型,并调用相应的预览组件进行展示。无论是常见的图片文件,还是复杂的PDF、Excel文档,都能在我们的系统中得到清晰、准确的预览效果。
此外,我们还提供了前后端完整接口示例,展示了如何在Vue3前端与后端服务器之间进行高效的数据交互。通过详细的接口定义和示例代码,开发者可以快速地理解并实现前后端的数据通信,为项目的快速迭代和部署提供了有力保障。
最后,在生产环境注意事项部分,我们总结了在实际部署过程中可能遇到的问题及解决方案,如性能优化、安全性考虑等。这些宝贵的经验分享将帮助开发者更好地将项目从开发环境迁移到生产环境,确保系统的稳定性和可靠性。综上所述,本文不仅提供了丰富的功能实现,还为开发者提供了全面的开发指导和实战经验分享。
相关文章:
Vue3实现文件上传、下载及预览全流程详解(含完整接口调用)
文章目录 一、环境准备1.1 创建Vue3项目1.2 安装依赖1.3 配置Element Plus 二、文件上传实现2.1 基础上传组件2.2 自定义上传逻辑(Axios实现) 三、文件下载实现3.1 直接下载(已知文件URL)3.2 后端接口下载(二进制流&am…...
【云原生】SpringCloud-Spring Boot Starter使用测试
目录 Spring Boot Starter是什么? 以前传统的做法 使用 Spring Boot Starter 之后 starter 的理念: starter 的实现: ?创建Spring Boot Starter步骤 在idea新建一个starter项目、直接执行下一步即可生成项目。 ?在xml中加入如下配置…...
介绍下pdf打印工具类 JasperPrint
JasperPrint 工具类深度解析 JasperPrint 是 JasperReports 框架中实现 PDF 打印的核心载体类,其本质是 填充数据后的可打印报表对象,承担着从模板编译、数据填充到格式输出的全流程控制。以下从 7 个维度展开深度解析: 一、核心定位与生命周…...
idea中或pycharm中编写Markdown文件
参考 ltjt_aiseek: seek_backend_py 项目 数智科技ai探索API接口开发 1. 安装 Django 框架 在开始创建 Django 项目之前,需要先安装 Django 框架。可以通过 PyCharm 的终端或者系统的命令行工具来完成安装。 使用 PyCharm 终端安装 打开 PyCharm,如果…...
Go红队开发—并发编程
文章目录 并发编程go协程chan通道无缓冲通道有缓冲通道创建⽆缓冲和缓冲通道 等协程sync.WaitGroup同步Runtime包Gosched()Goexit() 区别 同步变量sync.Mutex互斥锁atomic原子变量 SelectTicker定时器控制并发数量核心机制 并发编程阶段练习重要的细节端口扫描股票监控 并发编程…...
使用自动化运维工具 Ansible 集中化管理服务器
一、概述 Ansible 是一款为类 Unix 系统开发的自由开源的配置和自动化工具 官方网站:https://www.ansible.com/ Ansible 成立于 2013 年,总部设在北卡罗来纳州达勒姆,联合创始人 ad Ziouani 和高级副总裁 Todd Barr都是红帽的老员工。Ansible 旗下的开源软件 Ansible 十分…...
数据集笔记:新加坡 一些交通的时间序列统计量
1 机动车年度保有量 data.gov.sg 各类机动车年度保有量 数据范围:2005年1月 - 2020年12月 1.1 数据说明 非高峰时段车辆 包括周末车(Weekend Cars)和 修订版非高峰时段车辆(Revised Off Peak Cars),该…...
企业jsapi_ticket,java举例
在企业微信开发中,使用 Java 获取 jsapi_ticket 并生成签名的步骤如下。以下是完整的 Java 示例代码。 1. 获取 jsapi_ticket 的流程 获取 access_token。 使用 access_token 获取 jsapi_ticket。 使用 jsapi_ticket 生成签名(signature)。…...
【FL0090】基于SSM和微信小程序的球馆预约系统
🧑💻博主介绍🧑💻 全网粉丝10W,CSDN全栈领域优质创作者,博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战,以及程序定制化开发…...
智能图像处理平台:图像处理配置类
这里我们先修改一下依赖,不用JavaCV,用openCV。 导入依赖: <!-- JavaCV 依赖,用于图像和视频处理 --> <!-- <dependency>--> <!-- <groupId>org.bytedeco</groupId>--> &l…...
《深度剖析:生成对抗网络中生成器与判别器的高效协作之道》
在人工智能的前沿领域,生成对抗网络(GAN)以其独特的对抗学习机制,为数据生成和处理带来了革命性的变革。生成器与判别器作为GAN的核心组件,它们之间的协作效率直接决定了GAN在图像生成、数据增强、风格迁移等众多应用中…...
【多模态大模型论文精读】MinMo语音交互大模型
写在前面:你需要一个更丝滑的语音助手 想象一下,你与一个语音助手对话,不再需要“嘿,Siri”或“小爱同学”这样的唤醒词,也不需要等待它一字一句地蹦出回复。你们可以像朋友一样,随时打断、插话,甚至同时说话。语音助手不仅能听懂你说了什么,还能理解你的语气、情感,…...
22-接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 方法一:双指针法 思路 使用两个指针 left 和 right 分别指向数组的两端,同时记录左边的最大高度 leftMax 和右边的最大高度 rig…...
如何长期保存数据(不包括云存储)最安全有效?
互联网各领域资料分享专区(不定期更新): Sheet 前言 这个问题需要考虑多个方面,比如存储介质的寿命、数据完整性、访问的便捷性,还有成本等因素。长期保存的话,存储介质的耐久性很重要。比如常见的硬盘、SSD、光盘、磁带等,各有优缺点。机械硬盘(HDD)的寿命一般在3-5年,…...
k8s拉取harbor镜像部署
在k8s中创建凭证 首先在节点docker登录harbor, 登录成功之后会在$HOME/.docker/ 生成一个config.json文件,这个就是登录凭证,后面docker pull就不需要再登录了。但是如果在k8s发布pod或者deploment时,这个凭证要在k8s中创建一个对…...
一周一个Unity小游戏2D反弹球游戏 - 球板的发球
前言 本文将实现当游戏开始时球在球板上,且不具备物理性,在Windows平台上通过点击屏幕来球发射,安卓平台上当手指触摸到屏幕上时进行发球,并此时开始具备物理性。 发球逻辑 首先在球板上创建一个球的发射点,新建一个空的游戏物体,并命名为BallPoint,并将其作为SpringBoa…...
C 语言共用体:深入理解与实践】
目录 一、引言 二、共用体的定义和基本语法 三、共用体的使用 3.1 声明共用体变量 3.2 给共用体成员赋值 3.3 共用体的内存布局 四、共用体的应用场景 4.1 节省内存空间 4.2 处理不同类型的数据 五、共用体使用的注意事项 六、总结 一、引言 在 C 语言中,共…...
Oracle性能调优(一):时间模型统计
Oracle性能调优(一):时间模型统计 时间模型统计视图时间模型统计指标时间模型统计视图 📖 DB Time的含义: DB Time表示前台会话在数据库调用中所花费的总时间,它是衡量数据库实例总负载的一个重要指标。DB Time是从实例启动时开始累计测量的,其计算方法是将所有前台会话…...
012 rocketmq事务消息
文章目录 事务消息概念介绍交互流程事务消息原理TransactionListener接⼝TransactionProducer.javaTransactionConsumer.java 事务消息 内置topic中的消息对消费者不可见 本地事务mq消息事务消息 消息队列 RocketMQ 版提供的分布式事务消息适⽤于所有对数据最终⼀致性有强需求…...
SpringBoot原理-02.自动配置-概述
一.自动配置 所谓自动配置,就是Spring容器启动后,一些配置类、bean对象就自动存入了IOC容器当中,而不需要我们手动声明,直接从IOC容器中引入即可。省去了繁琐的配置操作。 我们可以首先将spring项目启动起来,里面有一…...
知识图谱+智能问诊预诊系统vue+django+neo4j架构、带问诊历史
文章结尾部分有CSDN官方提供的学长 联系方式名片 文章结尾部分有CSDN官方提供的学长 联系方式名片 关注B站,有好处! 🤍编号:D032 🤍智能问答:智能问答自诊、预诊功能,同时可以保存问答历史 &…...
DeepSeek 助力 Vue3 开发:打造丝滑的悬浮按钮(Floating Action Button)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
Java数据结构_一篇文章了解常用排序_8.1
本文所有排序举例均默认为升序排列。 目录 1. 常见的排序算法 2. 常见排序算法的实现 2.1 插入排序 2.1.1 基本思想: 2.1.2 直接插入排序 2.1.3 希尔排序(缩小增量排序) 2.2 选择排序 2.2.1 基本思想: 2.2.2 直接选择排…...
(南京观海微电子)——倍压设计与应用
在电路设计过程中,当后级需要的电压比前级高出数倍而所需要的电流并不是很大时,就可以使用倍压整流电路。倍压整流:可以将较低的交流电压,用耐压较高的整流二极管和电容器,“整”出一个较高的直流电压。 01 倍压整流电…...
AtCoder Beginner Contest AT_abc395_d ABC395D Pigeon Swap 题解
前言 在谎言中迷茫,试图躲避瓶颈。 可惜细节太多,浪费五发罚时。 一个绿名用户,被出题人卡住。 八十六分钟多,才看见一抹绿。 本题解 LaTeX \LaTeX LATEX 格式可能不太美观,以内容为主。 题目大意 有一群鸽子和它…...
网络安全-使用DeepSeek来获取sqlmap的攻击payload
文章目录 概述DeepSeek使用创建示例数据库创建API测试sqlmap部分日志参考 概述 今天来使用DeepSeek做安全测试,看看在有思路的情况下实现的快不快。 DeepSeek使用 我有一个思路,想要测试sqlmap工具如何dump数据库的: 连接mysql数据库&#…...
【含文档+PPT+源码】基于SpringBoot+Vue医药知识学习与分享平台的设计与实现
项目介绍 本课程演示的是一款 基于SpringBootVue医药知识学习与分享平台的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署…...
coze生成的工作流,发布后,利用cmd命令行执行。可以定时发日报,周报等。让他总结你飞书里面的表格。都可以
coze生成的工作流,发布后,利用cmd命令行执行。可以定时发日报,周报等。让他总结你飞书里面的表格。都可以。 很简单。 准备工作,先发布你的工作流,和发布应用。 然后,点击扣子API 。 申请一个࿰…...
iOS for...in 循环
0x00 循环遍历一 输出结果是什么? NSMutableArray *marr [1, 2, 3].mutableCopy; for (NSNumber *number in marr) {NSLog("%", number);marr [4, 5, 6].mutableCopy; } NSLog("%", marr);0x01 循环遍历二 输出结果是什么? NS…...
《操作系统 - 清华大学》 9 -1:进程调度:背景
进程调度:基础概念与调度策略详解 在进程调度这部分,我们会涉及以下内容:背景介绍、各种各样的调度算法(包括通用操作系统的调度算法以及针对实时系统的算法),还会额外介绍一种调度算法。 一、CPU调度的背…...
