项目是上传oss接口的 但是视频高达小100M,所以需要用真实的进度条
(项目是只上传一个文件 多个文件需要自行修改)
特别注意:当文件上传删除时 浏览器报错 “reqs[uid].abort is not a function"
原因一:api 中 http-request这个方法 是一个异步方法,不能使用 async 不然会报错误
原因一:如果还是有这个错误请看下面代码 有解决方法!!!!
效果图:
方法一:纯前端实现
优点:不需要后端单独写接口
缺点:只能获取文件的上传速度 并不能保证结束后 接口一定返回地址
方法二:前端+后端实现
优点:进度条是真实的,但是太小文件上传时进度条的效果有些不太完美
缺点:需要后端单独写获取文件上传oss的接口
<template>
<el-upload
:limit="1"
:on-preview="handlePictureCardPreview"
class="el-uploadfeng"
ref="files"
action="#"
:file-list="fileList"
:before-upload="beforeAvatarUpload"
:on-change="changeData"
accept=".mp3,.mp4,.gif,.png,.jpg,.mpeg,.mpg"
:http-request="handleRequest"
:before-remove="handleBeforeRemove"
:on-remove="handleRemove"
>
<i class="el-icon-plus" v-if="fileList.length == 0 && !isUpload" ></i>
</el-upload>
<div class="newpro">
<el-progress
v-if="isUpload"
:stroke-width="10"
:percentage="progressPercent"
style="width: 100%"
></el-progress>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
uploadTimer: null,//调取进度条的轮询定时器
isUpload: false,//文件是否上传中
progressPercent: 0,//进度条当前进度
curPercentage: 0,
fileList: [],//上传文件
currentFile: {},//当去上传的文件
};
},
watch: {
//监听文件是否上传
isUpload: {
handler(val, oldVal) {
if (this.isUpload) {
this.uploadTimer = setInterval(async () => {
//需要定时执行的代码
this.progressPercent = await this.getProgress(this.currentFile);
}, 1000);
} else {
clearInterval(this.uploadTimer);
this.currentFile = {};
}
},
deep: true,
},
},
methods: {
beforeAvatarUpload(file, fileList) {
console.log(file, 99999999999999);
},
async getProgress(file) {
var that = this;
console.log("🚀 ~ handleRequest ~ data222:", file.uid);
var progress = 0;
await axios
.get('获取进度条接口地址')
.then(async (res) => {
//percent是后端返回的进度
progress = Number(res.data.percent);
if (progress == 100) {
this.isUpload = false;
clearInterval(this.uploadTimer);
that.uploadTimer = null;
await that.handlePicSuccess(res.data, file);
this.currentFile = {};
this.$forceUpdate();
}
});
return progress;
},
handleRequest(option) {
var that = this;
const { onProgress, onSuccess, onError } = option;
this.progressPercent = 0;
this.currentFile = option.file;
let formdata = new FormData();
formdata.append("file", option.file);
formdata.append("fileName", option.file.fileNamee);
formdata.append("uid", option.file.uid);
console.log("🚀 ~ handleRequest ~ formdata:", formdata);
this.isUpload = true;
// 这是方法一的开始
// const config = {
// onUploadProgress: (progressEvent) => {
// // progressEvent.loaded:已上传文件大小
// // progressEvent.total:被上传文件的总大小
// this.progressPercent = Number(
// ((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
// );
// },
// };
// 这是方法一的结束
axios
.post('文件上传oss接口地址 ',
formdata,
//config,这是方法一的配置
)
.then((res) => {
console.log("🚀 ~ this.$axios.post ~ res111:", res);
if (res.data.code == 0) {
that.fileList[that.fileList.length - 1].status = "done";
onSuccess();
} else {
that.fileList[that.fileList.length - 1].ststus = "error";
onError();
}
});
//如果浏览器出现 reqs[uid].abort is not a function 加上即可
// var prom = new Promise((resolve, reject) => {});
// prom.abort = () => {};
// return prom;
},
//文件上传成功
handlePicSuccess(res, file) {
console.log(res, file, "999999999");
if (res.msg == "success") {
this.addForm.url = res.url;
this.fileList.push({
name: file.name,
url: res.url,
});
this.$message.success("上传成功");
this.isUpload = false;
} else {
this.$message.error("上传失败");
}
},
//文件删除前
handleBeforeRemove(file, fileList) {
console.log(file, fileList, "file, fileListfile, fileListfile, fileList");
this.$refs.files.clearFiles();
clearInterval(this.uploadTimer);
this.isUpload = false;
this.currentFile = {};
this.$forceUpdate();
},
//文件删除
handleRemove(file, fileList) {
this.addForm.url = "";
this.fileList = fileList;
//this.uploadTimer = null;
clearInterval(this.uploadTimer);
this.isUpload = false;
this.currentFile = {};
this.$forceUpdate();
},
},
beforeDestroy() {
clearInterval(this.uploadTimer);
},
};
</script>
<style lang="less">
.newpro .el-progress-bar__inner:before {
content: "";
width: 100%;
height: 100%;
display: block;
background-image: repeating-linear-gradient(
-45deg,
hsla(0, 0%, 100%, 0.15) 25%,
transparent 0,
transparent 50%,
hsla(0, 0%, 100%, 0.15) 0,
hsla(0, 0%, 100%, 0.15) 75%,
transparent 0,
transparent
);
background-size: 40px 40px;
animation: mymove 2s linear infinite;
}
@keyframes mymove {
0% {
background-position: 0;
}
25% {
background-position: 50px;
}
50% {
background-position: 100px;
}
75% {
background-position: 150px;
}
100% {
background-position: 200px;
}
}
</style>