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

【篇三】在vue3上实现阿里云oss文件直传

之前写了两篇关于文件上传的文章
【篇一】使用springboot+vue实现阿里云oss上传
【篇二】使用springboot+vue实现阿里云oss文件直传,解决大文件分片上传问题
今天介绍一下在vue3中实现阿里云oss文件直传,主要是基于篇二中的源码进行修改,看具体代码

OssFileUpload组件

<template><div class="upload-file"><el-upload:multiple="multiple":accept="accept.join(',')"action="#":http-request="handleUpload":before-upload="handleBeforeUpload":file-list="fileList":limit="limit":on-exceed="handleExceed":show-file-list="false":data="data"class="upload-file-uploader"ref="fileUpload"><!-- 上传按钮 --><el-button type="primary">选取文件</el-button><template v-if="multiple"> (按住Ctrl键多选)</template></el-upload><!-- 上传提示 --><div class="el-upload__tip" slot="tip" v-if="showTip && fileList.length<=0"><span v-if="limit"> 1、文件数量限制为 <b style="color: #f56c6c">{{ limit }}个</b></span><span v-if="fileSize"> 2、文件大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b><br></span><span v-if="fileType"> 3、文件格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b><br></span></div><!-- 文件列表 --><transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul" height="485"><li v-for="(file, index) in fileList" :key="file.uid || index " class="el-upload-list__item ele-upload-list__item-content"><el-link :href="file.url" :underline="false" target="_blank"><span class="`el-icon-d`ocument"> {{ file.name }} </span></el-link><div class="ele-upload-list__item-content-action"><el-link :underline="false" @click="handleDelete(index)" type="danger" style="width: 50px">删除</el-link></div></li></transition-group></div>
</template><script setup>
import {handleMD5} from '@/utils/md5';
import {generateOssPolicy} from "@/api/file/file";
import {POST} from "@/utils/request";const props = defineProps({// 是否可多选multiple: {type: Boolean,default: true,},// 值value: [String, Object, Array],// 数量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 5,},// 文件类型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array,default: () => ["doc", "xls", "xlsx", "ppt", "txt", "pdf"],},accept: {type: Array,default: () => [".doc", ".xls", ".xlsx", ".ppt", ".txt", ".pdf"],},// 是否显示提示isShowTip: {type: Boolean,default: true},// 是否重命名rename: {type: Boolean,default: true}
});const {proxy} = getCurrentInstance();
const emit = defineEmits();
const number = ref(0);
const uploadList = ref([]);
const fileList = ref([]);
const data = ref({});
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize)
);
watch(() => [props.value, props.rename], ([val1, val2]) => {if (val1) {let temp = 1;// 首先将值转为数组const list = Array.isArray(val1) ? val1 : props.value.split(',');// 然后将数组转为对象数组fileList.value = list.map(item => {if (typeof item === "string") {item = {name: item.name, url: item.url};}item.uid = item.uid || new Date().getTime() + temp++;return item;});} else {fileList.value = [];return [];}if (val2) {data.value = {rename: val2}}
}, {deep: true, immediate: true});// 上传前校检格式和大小
function handleBeforeUpload(file) {// 校检文件类型if (props.fileType) {const fileName = file.name.split('.');const fileExt = fileName[fileName.length - 1];const isTypeOk = props.fileType.indexOf(fileExt) >= 0;if (!isTypeOk) {proxy.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`);return false;}}// 校检文件大小if (props.fileSize) {const isLt = file.size / 1024 / 1024 < props.fileSize;if (!isLt) {proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);return false;}}//增加判断逻辑:如果是视频文件,获取视频分辨率const isVideo = file.type === "video/mp4" || file.type === "video/webm";if (isVideo) {// 创建一个视频元素const video = document.createElement('video');video.preload = 'metadata';// 设置视频源video.src = URL.createObjectURL(file);// 监听加载元数据完成video.onloadedmetadata = () => {URL.revokeObjectURL(video.src); // 释放URL对象const width = video.videoWidth;const height = video.videoHeight;// 获取视频时长const duration = video.duration;file.width = width;file.height = height;file.duration = duration;// 这里可以根据分辨率做进一步处理,例如检查分辨率是否符合要求};}proxy.$modal.loading("正在上传文件,请稍候...");number.value++;return true;
}// 文件个数超出
function handleExceed() {proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
}// 删除文件
function handleDelete(index) {fileList.value.splice(index, 1);emit("update:value", listToString(fileList.value));
}// 上传结束处理
function uploadedSuccessfully() {if (number.value > 0 && uploadList.value.length === number.value) {fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);uploadList.value = [];number.value = 0;emit("update:value", listToString(fileList.value));proxy.$modal.closeLoading();}
}/** 上传操作 */
function handleUpload(file) {handleMD5(file.file).then(md5 => {const data = {fileName: file.file.name,md5: md5,rename: props.rename// 增加视频的分辨率、播放时长,后端接收后再通过回调接口返回,前端即可获取width: file.file.width,height: file.file.height,duration: file.file.duration,};generateOssPolicy(data).then((response) => {let data = response.datalet formData = new FormData();formData.append('OSSAccessKeyId', data.accessKeyId);formData.append('signature', data.signature);formData.append('policy', data.policy);formData.append('key', data.filePath);formData.append('callback', data.callback);formData.append('success_action_status', 200);formData.append('file', file.file);POST(data.host, formData).then((res) => {let params = res.dataif (params.code !== 200) {proxy.$modal.msgError(params.msg);return;}uploadList.value.push(params.data);uploadedSuccessfully();proxy.$modal.msgSuccess("上传成功");});})})
}// 获取文件名称
function getFileName(name) {if (name.lastIndexOf("/") > -1) {return name.slice(name.lastIndexOf("/") + 1);} else {return "";}
}// 对象转成指定字符串分隔
function listToString(list, separator) {let str = "";separator = separator || ",";for (let i in list) {str += list[i].url + separator;}return str !== '' ? str.substring(0, str.length - 1) : '';
}//暴露给父组件,否则无法获取值
defineExpose({fileList
})
</script><style scoped lang="scss">
.upload-file-uploader {margin-bottom: 5px;
}
.upload-file-list {max-height: 420px;overflow-y: auto;
}
.el-upload__tip span {display: block;width: fit-content;line-height: 20px;
}
.upload-file-list .el-upload-list__item {border: 1px solid #e4e7ed;line-height: 2;margin-bottom: 10px;position: relative;
}
.upload-file-list .ele-upload-list__item-content {display: flex;justify-content: space-between;align-items: center;color: inherit;
}
.ele-upload-list__item-content-action .el-link {margin-right: 10px;
}
</style>

父组件引用

/** 提交按钮 */
function submitForm() {proxy.$refs["editForm"].validate(valid => {if (valid) {// 获取子组件的fileListform.value.files = proxy.$refs.upload.fileListif (!Array.isArray(form.value.files) || form.value.files.length <= 0) {proxy.$alert("请上传文件");return false;}//增加了多个文件属性字段form.value.download = form.value.files[0].urlform.value.name = form.value.files[0].nameform.value.userName = form.value.files[0].userform.value.md5 = form.value.files[0].md5form.value.size = form.value.files[0].sizesave(form.value).then(() => {proxy.$modal.msgSuccess("操作成功");open.value = false;getList();});}});
}

后端代码除组装callbackBody增加了几个参数外,逻辑基本相同,故省略。

相关文章:

【篇三】在vue3上实现阿里云oss文件直传

之前写了两篇关于文件上传的文章 【篇一】使用springbootvue实现阿里云oss上传 【篇二】使用springbootvue实现阿里云oss文件直传&#xff0c;解决大文件分片上传问题 今天介绍一下在vue3中实现阿里云oss文件直传&#xff0c;主要是基于篇二中的源码进行修改&#xff0c;看具体…...

OceanBase v4.2 特性解析:对Json与Xml的扩展支持

1. 背景 OceanBase的Oracle模式当前已实现对XMLType类型的支持&#xff0c;不仅包含了基本的构造、查询、更新以及格式转换功能&#xff0c;还支持使用Xpath查询从XML数据中提取特定值。在V 4.2.2 版本中&#xff0c;我们进一步扩展了Oracle模式下对XMLType的支持&#xff0c;…...

《框架封装 · 统一异常处理和返回值包装》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

深入WebKit:揭秘复杂文档的高效渲染之道

深入WebKit&#xff1a;揭秘复杂文档的高效渲染之道 在当今信息爆炸的时代&#xff0c;网页不再仅仅是简单的文本和图片的集合&#xff0c;而是充满了复杂布局和丰富媒体内容的交互式平台。WebKit 作为众多流行浏览器的心脏&#xff0c;其布局引擎承担着将 HTML、CSS 代码转换…...

进程的控制-孤儿进程和僵尸进程

孤儿进程 &#xff1a; 一个父进程退出&#xff0c;而它的一个或多个子进程还在运行&#xff0c;那么那些子进程将成为孤儿进程。孤儿进程将被 init 进程( 进程号为 1) 所收养&#xff0c;并由 init 进程对它们完成状态收集工作 为了释放子进程的占用的系统资源&#xff1a; …...

【Unity navigation面板】

【Unity navigation面板】 Unity的Navigation面板是一个集成在Unity编辑器中的界面&#xff0c;它允许开发者对导航网格&#xff08;NavMesh&#xff09;进行配置和管理。 Unity Navigation面板的一些关键特性和功能&#xff1a; 导航网格代理&#xff08;NavMesh Agent&…...

二刷算法训练营Day53 | 动态规划(14/17)

目录 详细布置&#xff1a; 1. 392. 判断子序列 2. 115. 不同的子序列 详细布置&#xff1a; 1. 392. 判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余…...

将缓冲文件写到磁盘中的命令sync

将缓冲文件写到磁盘中的命令sync There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated should leave quick…...

灵活视图变换器:为扩散模型设计的革新图像生成架构

在自然界中&#xff0c;图像的分辨率是无限的&#xff0c;而现有的图像生成模型在跨任意分辨率泛化方面存在困难。虽然扩散变换器&#xff08;DiT&#xff09;在特定分辨率范围内表现出色&#xff0c;但在处理不同分辨率的图像时却力不从心。为了克服这一限制&#xff0c;来自上…...

[终端安全]-1 总体介绍

有朋友一直在和笔者研讨智驾安全这个热门话题&#xff0c;笔者十多年工作从不离终端安全这个核心话题&#xff08;芯片安全、操作系统安全、应用安全&#xff09;&#xff0c;近来也一直在梳理终端安全体系&#xff1b;手机、汽车皆是我们生活中应用最普遍的智能终端&#xff0…...

Mysql5.7并发插入死锁问题

死锁的产生条件 互斥、请求和保持、不可剥夺、循环等待 MySQL锁类型 死锁复现 环境&#xff1a;Mysql 5.7版本&#xff0c;Innodb引擎&#xff0c;可重复度隔离级别 并发场景下使用duplicate key update插入或更新数据可能会造成死锁&#xff0c;下面就产生死锁的条件进行模…...

网络“ping不通”,如何排查和解决呢?

网络问题往往复杂且难以预测&#xff0c;其中“ping不通”是常见的网络故障之一。 1. 确认问题现象 首先&#xff0c;明确问题是完全无法ping通(无响应)还是ping通但有高延迟或丢包。这有助于缩小问题范围。 2. 本地检查 网络接口状态&#xff1a;使用ifconfig(Linux)或ipc…...

日常学习--20240706

1、udp协议的特点有哪些&#xff1f; a、无连接&#xff0c;发送和接收数据不需要建立连接&#xff0c;开销小&#xff0c;实时性好 b、不可靠传输&#xff0c;不保证数据包能够到达目的地&#xff0c;也不保证数据包的顺序 c、面向数据报的&#xff0c;以数据报形式发送数据…...

入门PHP就来我这(高级)12 ~ 获取数据

有胆量你就来跟着路老师卷起来&#xff01; -- 纯干货&#xff0c;技术知识分享 路老师给大家分享PHP语言的知识了&#xff0c;旨在想让大家入门PHP&#xff0c;并深入了解PHP语言。 1 从结果集中获取一行作为对象 表中数据行如下&#xff1a; 利用mysqli_fetch_array()函数获…...

AIGC专栏12——EasyAnimateV3发布详解 支持图文生视频 最大支持960x960x144帧视频生成

AIGC专栏12——EasyAnimateV3发布详解 支持图&文生视频 最大支持960x960x144帧视频生成 学习前言项目特点生成效果相关地址汇总项目主页Huggingface体验地址Modelscope体验地址源码下载地址 EasyAnimate V3详解技术储备Diffusion Transformer (DiT)Hybrid Motion ModuleU-V…...

【python】python猫眼电影数据抓取分析可视化(源码+数据集+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…...

Android 四大组件

1. Activity 应用程序中&#xff0c;一个Activity通常是一个单独的屏幕&#xff0c;它上面可以显示一些控件&#xff0c;也可以监听并对用户的事件做出响应。 Activity之间通过Intent进行通信&#xff0c;在Intent 的描述结构中&#xff0c;有两个最重要的部分&#xff1a;动…...

【Python】已解决:ModuleNotFoundError: No module named ‘nltk’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘nltk’ 一、分析问题背景 在使用Python进行自然语言处理或文本分析时&#xff0c;我们经常会用到各种库来辅助我们的工…...

【Docker系列】Docker 命令行输出格式化指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

使用Netty构建高性能的网络应用

使用Netty构建高性能的网络应用 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; Netty是一个基于Java NIO的异步事件驱动的网络应用框架&#xff0c;专为快速开发高性能、高可靠性的网络服务器和客户…...

手把手教你本地部署DeepSeek-R1 1.5B:极速CPU推理,隐私安全有保障

手把手教你本地部署DeepSeek-R1 1.5B&#xff1a;极速CPU推理&#xff0c;隐私安全有保障 1. 项目概述 DeepSeek-R1 1.5B是一个经过蒸馏优化的轻量级语言模型&#xff0c;专为本地CPU推理场景设计。相比原版模型&#xff0c;它保留了核心的逻辑推理能力&#xff0c;同时大幅降…...

在 Windows 上实现 SSH 掉线重连与会话持久化

在 Windows 上实现 SSH 掉线重连与会话持久化&#xff1a;完整方案指南 SSH 是连接和管理远程 Linux 服务器的必备工具&#xff0c;但在 Windows 环境下&#xff0c;网络波动或电脑休眠常常导致 SSH 连接中断&#xff0c;正在运行的任务&#xff08;如模型训练、编译等&#xf…...

告别联网烦恼:uv离线安装科学计算包的3种实战姿势(NumPy/TensorFlow实测)

数据科学家必备&#xff1a;三种高效离线安装Python科学计算包的终极方案 实验室的服务器突然断网了&#xff0c;而你的TensorFlow模型训练正进行到关键时刻——这种场景对数据科学家来说简直是噩梦。别担心&#xff0c;离线安装Python包并非无解难题。本文将带你掌握三种经过实…...

RyzenAdj终极指南:3分钟解锁AMD锐龙处理器隐藏性能

RyzenAdj终极指南&#xff1a;3分钟解锁AMD锐龙处理器隐藏性能 【免费下载链接】RyzenAdj Adjust power management settings for Ryzen APUs 项目地址: https://gitcode.com/gh_mirrors/ry/RyzenAdj 你是否感觉自己的AMD锐龙笔记本性能被限制住了&#xff1f;玩游戏时帧…...

Qwen3.5-2B轻量化部署:4GB显存GPU跑通多模态推理的完整环境配置

Qwen3.5-2B轻量化部署&#xff1a;4GB显存GPU跑通多模态推理的完整环境配置 1. 模型概述 Qwen3.5-2B是Qwen3.5系列中的轻量化多模态基础模型&#xff0c;仅有20亿参数规模&#xff0c;专为低功耗、低门槛部署场景设计。该模型具有以下核心特点&#xff1a; 资源占用低&#…...

智能监控新选择:基于实时口罩检测-通用模型的自动告警系统搭建

智能监控新选择&#xff1a;基于实时口罩检测-通用模型的自动告警系统搭建 1. 引言&#xff1a;智能防疫监控的迫切需求 在公共场所管理中&#xff0c;确保人员佩戴口罩是防疫工作的重要环节。传统的人工检查方式存在效率低、成本高、易遗漏等问题。基于计算机视觉的智能监控…...

Sony FCB-EV9500L LVDS图像闪烁问题分析

在基于高清图像采集与远距离传输的系统中&#xff0c;Sony FCB-EV9500L作为一款高性能一体化机芯模组&#xff0c;被广泛应用于安防监控、工业视觉及医疗设备等领域。在实际应用过程中&#xff0c;部分工程师反馈其在LVDS传输链路中出现图像闪烁问题。本文将围绕LVDS信号特性、…...

Intv_AI_MK11 处理时序数据:LSTM 思想在对话状态跟踪中的应用

Intv_AI_MK11 处理时序数据&#xff1a;LSTM 思想在对话状态跟踪中的应用 1. 引言&#xff1a;对话状态跟踪的挑战 在多轮对话系统中&#xff0c;准确跟踪对话状态是核心挑战之一。传统方法往往难以有效捕捉对话历史中的长期依赖关系&#xff0c;导致系统在复杂对话场景中容易…...

SEO培训需要什么基础知识

SEO培训需要什么基础知识 SEO培训是一个复杂且不断变化的领域。想要在这个领域取得成功&#xff0c;你需要具备一些基础知识。这些知识不仅能帮助你理解搜索引擎优化的基本原理&#xff0c;还能为你的职业发展提供坚实的基础。SEO培训需要哪些基础知识呢&#xff1f;本文将从多…...

Java学习——数据类型

目录 一、概述 二、基本数据类型 1、数值型 2、字符型 3、布尔型 三、引用数据类&#xff08;后期补充&#xff09; 1、类 2、接口 3、数组 4、枚举 5、注解 四、数据类型转换 1、概述 2、隐式转换&#xff08;自动类型转换&#xff09; 3、显式转换&#xff08…...