当前位置: 首页 > news >正文

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)
})

六、注意事项

  1. 安全验证:所有文件接口需进行身份验证
  2. 文件大小限制:Nginx需配置client_max_body_size
  3. 文件存储
    • 敏感文件不要存储在公开目录
    • 使用OSS云存储更佳
  4. 预览安全
    • 防止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 自定义上传逻辑&#xff08;Axios实现&#xff09; 三、文件下载实现3.1 直接下载&#xff08;已知文件URL&#xff09;3.2 后端接口下载&#xff08;二进制流&am…...

普通人高效使用DeepSeek指南?

李升伟 整理 DeepSeek&#xff08;深度求索&#xff09;作为一款智能搜索引擎或AI工具&#xff0c;普通人可以通过以下方式高效利用它&#xff0c;提升学习、工作和生活效率&#xff1a; --- ### **一、基础功能&#xff1a;精准搜索** 1. **明确需求提问** 用自然语言…...

基于JAVA+Spring+mysql_快递管理系统源码+设计文档

文末获取源码数据库文档 感兴趣的可以先收藏&#xff0c;有毕设问题&#xff0c;项目以及论文撰写等问题都可以和博主沟通&#xff0c;尽最大努力帮助更多的人&#xff01; 摘 要 随着物流行业信息化的深入使得物流过程中货物的状态和变化透明化&#xff0c;现代信息化的接入使…...

《从0到1:用Python在鸿蒙系统开发安防图像分类AI功能》

在人工智能与移动应用深度融合的当下,类目标签AI功能成为众多行业提升效率和用户体验的关键技术。本文聚焦于HarmonyOS NEXT API 12及以上版本,以图像分类在智能家居安防领域的应用为例,为开发者详细阐述如何利用Python开发类目标签AI功能,助力鸿蒙技术在该领域的创新应用。…...

第十四届蓝桥杯大赛软件赛国赛C/C++大学C组

A 【跑步计划——日期问题】-CSDN博客 B 【残缺的数字】-CSDN博客 C 题目 代码 #include <bits/stdc.h> using namespace std;void change(int &x) {int sum 0, t x;while(t){sum t % 10;t / 10;}x - sum; } int main() {int n;cin >> n;int ans 0;…...

黑龙江省地标-DB31/T 862-2021 “一网通办”政务服务中心建设和运行规范

黑龙江省智慧政务服务&#xff1a;标准规范引领服务新篇章 1. 引言 在数字化转型的大潮中&#xff0c;智慧政务服务作为提升政府服务效能、优化营商环境、增强民众获得感的重要手段&#xff0c;正受到越来越多的关注。黑龙江省紧跟时代步伐&#xff0c;出台了一系列智慧政务服…...

基于SpringBoot的美妆购物网站系统设计与实现现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

如何评估所选择的PHP后端框架的性能?

大家在选择PHP后端框架的时候&#xff0c;如果想评估其性能如何&#xff0c;能不能扛得住你的项目&#xff1f;可以根据以下几点进行分析&#xff0c;帮助大家选择到更符合自己心目中的PHP后端框架。 1. 基准测试 基准测试是评估框架性能的基础方法&#xff0c;主要通过模拟高…...

快速搭建多语言网站的 FastAdmin 实践

快速搭建多语言网站的 FastAdmin 实践 引言 在全球化的背景下&#xff0c;越来越多的网站需要支持多种语言&#xff0c;以便满足不同用户的需求。FastAdmin 是一个基于 ThinkPHP 的快速后台开发框架&#xff0c;提供了丰富的功能和灵活的扩展性&#xff0c;非常适合用于快速搭…...

单片机中的flah和RAM

片机的 Flash 和 RAM 是两种关键的内存类型&#xff0c;分别用于存储程序代码和运行时数据。 Flash 存储器 用途&#xff1a;用于存储程序代码&#xff08;如固件&#xff09;和常量数据&#xff08;如查找表、字符串等&#xff09;。 特点&#xff1a; 非易失性&#xff1a;断…...

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.1.2典型应用场景:日志分析、实时搜索、推荐系统

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 为什么选择Elasticsearch&#xff1f;——典型应用场景深度解析1. 引言2. 日志分析&#xff1a;海量数据的实时洞察2.1 行业痛点2.2 ES解决方案关键技术实现&#xff1a; 2.…...

solidwork智能尺寸怎么对称尺寸

以构造轴为中心线就能画智能尺寸的对称尺寸。先点击边再点击构造线...

直播cdn原理

直播CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;的原理是通过将直播流分发到多个服务器节点&#xff0c;使用户可以从最近的节点获取数据&#xff0c;从而减少延迟和提高传输效率。以下是直播CDN原理的详细解读&#xff1a; 一、核心组成部…...

如何长期保存数据(不包括云存储)最安全有效?

互联网各领域资料分享专区(不定期更新): Sheet 前言 这个问题需要考虑多个方面,比如存储介质的寿命、数据完整性、访问的便捷性,还有成本等因素。长期保存的话,存储介质的耐久性很重要。比如常见的硬盘、SSD、光盘、磁带等,各有优缺点。机械硬盘(HDD)的寿命一般在3-5年,…...

【Java】I/O 流篇 —— 打印流与压缩流

目录 打印流概述字节打印流构造方法成员方法代码示例 字符打印流构造方法成员方法代码示例 打印流的应用场景 解压缩/压缩流解压缩流压缩流 Commons-io 工具包概述Commons-io 使用步骤Commons-io 常见方法代码示例 Hutool 工具包 打印流 概述 分类&#xff1a;打印流一般是指…...

更换k8s容器运行时环境为docker

更换k8s容器运行时环境为docker k8s-V1.24之后容器运行时默认是containerd&#xff0c;若想改为熟悉的docker作为运行时&#xff0c;需要做以下操作 在每个节点安装containerd、docker; 每个节点安装cri-docker&#xff1b; 调整kubelet配置并重启验证。 1.安装docker、con…...

【数字信号处理:从原理到应用的深度剖析】

一、数字信号处理的原理 数字信号处理&#xff08;DSP&#xff09;是一种通过数学算法对信号进行分析、处理和转换的技术。其核心在于对离散时间信号的操作&#xff0c;目的是提取有用信息或将信号转换为更易于解释的形式。 &#xff08;一&#xff09;信号的数字化过程 1. …...

Pytest之fixture的常见用法

文章目录 1.前言2.使用fixture执行前置操作3.使用conftest共享fixture4.使用yield执行后置操作 1.前言 在pytest中&#xff0c;fixture是一个非常强大和灵活的功能&#xff0c;用于为测试函数提供固定的测试数据、测试环境或执行一些前置和后置操作等&#xff0c; 与setup和te…...

FFmpeg入门:最简单的视频播放器

FFmpeg入门&#xff1a;最简单的视频播放器 FFmpeg入门第一篇&#xff0c;制作一个简单的MP4视频播放器。 整体流程 话不多说&#xff0c;直接上流程图 视频播放速率控制 这里可以直接看图中的帧率同步模块&#xff0c;可以分为如下几步 获取到当前帧的预期播放时间&…...

GitHub 语析 - 基于大模型的知识库与知识图谱问答平台

语析 - 基于大模型的知识库与知识图谱问答平台 GitHub 地址&#xff1a;https://github.com/xerrors/Yuxi-Know &#x1f4dd; 项目概述 语析是一个强大的问答平台&#xff0c;结合了大模型 RAG 知识库与知识图谱技术&#xff0c;基于 Llamaindex VueJS FastAPI Neo4j 构…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...