1. 引入 Qiniu 第三方插件
npm install qiniu-js
2. 在组件中引入
import * as qiniu from "qiniu-js";
3. 封装成组件
<template>
<div class="ft-plant-upload-button">
<button
v-if="!showProgress"
class="upload-btn"
type="ghost"
:disabled="percent > 0.01 && percent < 100"
@click="zh_uploadFile"
>
上传文件
</button>
<div class="progress-wraper" v-if="showProgress">
<div class="progress" v-if="percent > 0.01 && percent < 100">
<div
class="progress-bar"
role="progressbar"
aria-valuemin="0"
aria-valuemax="100"
:style="{ width: percent + '%' }"
></div>
</div>
<div class="precent" v-if="percent > 0.01 && percent < 100">
{{ percent || 0 }}%
<a-icon type="close-circle" @click="delClick" />
</div>
</div>
<div class="file-name">
{{ oldFileName }}
</div>
<input
type="file"
ref="evfile"
id="fileField"
@change="zh_uploadFile_change"
style="display: none"
/>
<video
ref="videoPlayerNew"
:src="videoUrl"
controls="controls"
style="display: none"
></video>
</div>
</template>
<script>
import * as qiniu from "qiniu-js";
import { GetUploadTokenApi } from "@/request/api/login";
import { message, Modal } from "ant-design-vue";
export default {
props: {
oldFileName: {
type: String,
default: "",
},
type: {
// 1 -- 音频 2 -- 视频
type: Number,
default: 1,
},
},
data() {
return {
subscription: null,
percent: 0,
showProgress: false,
size: "", // 视频大小
videoUrl: "", // 视频链接
videoTime: null, // 视频时长
};
},
methods: {
// 获取随机数
getRandom(num) {
var random = Math.floor(
(Math.random() + Math.floor(Math.random() * 9 + 1)) *
Math.pow(10, num - 1)
);
return random;
},
// 取消上传
delClick() {
let that = this;
Modal.confirm({
title: "提示",
content: "取消上传后需要重新上传, 是否确定取消上传",
okText: "确认",
okType: "danger",
cancelText: "取消",
onOk() {
let obj = {
fileCosKey: "",
fileUrl: "",
videoTime: 0,
fileSize: 0,
oldFileName: " ",
};
that.$emit("videoFn", obj);
that.showProgress = false;
that.$emit("changeOldFileName", " ");
that.percent = 0;
that.subscription.unsubscribe(); // 取消上传
},
});
},
//选择上传文件
zh_uploadFile() {
this.$refs.evfile.click();
},
//选择文件后触发的事件
zh_uploadFile_change(evfile) {
let that = this;
let fileName = this.$refs.evfile.files[0].name;
if (evfile) {
let endTitle = "";
let title = "";
if (this.type == 1) {
title = "audio";
endTitle = ".mp3";
} else if (this.type == 2) {
title = "video";
endTitle = ".mp4";
}
if (fileName.endsWith(endTitle)) {
this.$emit("changeOldFileName", this.$refs.evfile.files[0].name);
this.showProgress = true; // 显示上传过程
GetUploadTokenApi().then(({ code, data }) => {
if (code == 200) {
let obj = new Date();
let month =
obj.getMonth() + 1 < 10
? `0${obj.getMonth() + 1}`
: obj.getMonth() + 1;
let time = `${obj.getFullYear()}${month}${obj.getDate()}`;
let key = `/course/${title}/${time}/${time}${obj.getMinutes()}${obj.getSeconds()}${this.getRandom(
5
)}${endTitle}`;
var uptoken = data.upToken;
var file = evfile.target.files[0]; //Blob 对象,上传的文件
let config = {
useCdnDomain: true, // 表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false。
region: null, // 上传域名区域(z1为华北),当为 null 或 undefined 时,自动分析上传域名区域
// forceDirect: true,
};
let putExtra = {
fname: that.$refs.evfile.files[0].name, // 文件原文件名
params: {}, // 放置自定义变量: 'x:name': 'sex'
mimeType: null, // 限制上传文件类型,为 null 时表示不对文件类型限制;限制类型放到数组里: ["image/png", "image/jpeg", "image/gif"]
};
// observable是一个带有 subscribe 方法的类实例
var observable = qiniu.upload(
file,
key,
uptoken,
putExtra,
config
);
that.subscription = observable.subscribe({
// 上传开始
next: (result) => {
this.percent = result.total.percent.toFixed(2);
this.size = result.total.size;
},
error: (errResult) => {
message.error("上传失败"); // 上传错误后失败报错
console.log(errResult);
this.$emit("changeOldFileName", " ");
},
complete: (result) => {
message.success("上传成功");
that.showProgress = false;
this.videoUrl = `${data.domain}${result.key}`;
this.$refs.videoPlayerNew.onloadedmetadata = function () {
let obj = {
fileCosKey: result.key,
fileUrl: `${data.domain}${result.key}`,
// 获取音视频时长
videoTime: that.$refs.videoPlayerNew.duration.toFixed(2),
fileSize: that.size,
oldFileName: that.oldFileName,
};
// 后端需要的参数传递出去
that.$emit("videoFn", obj);
};
},
});
} else {
this.showProgress = false;
this.$emit("changeOldFileName", " ");
}
});
} else {
message.error("请上传正确的文件类型");
}
}
},
},
};
</script>
<style lang="less" scoped>
.ft-plant-upload-button {
vertical-align: middle;
.progress {
width: 85px;
height: 7px;
vertical-align: middle;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
background: silver;
-webkit-box-shadow: none !important;
box-shadow: none !important;
margin-left: 5px;
}
}
.upload-btn {
border: 1px solid #5084fe;
padding: 5px 23px;
outline: none;
border-radius: 4px;
cursor: pointer;
background: #fff;
color: #333;
}
.progress-wraper {
display: inline-block;
}
.progress {
width: 85px;
height: 7px;
vertical-align: middle;
display: inline-flex;
background: rgba(192, 192, 192, 1);
box-shadow: none !important;
margin-left: 5px;
.progress-bar {
display: inline-block;
background: rgba(80, 132, 254, 1);
}
}
.precent {
display: inline-block;
vertical-align: middle;
margin-left: 3px;
}
.file-name {
display: inline-block;
vertical-align: middle;
margin-left: 3px;
}
.add-courseware {
padding-left: 15px;
}
/deep/.anticon {
margin: 0 10px;
color: red;
}
</style>
4. 在页面中引入组件
<QiniuVideoAudio
:oldFileName="form.oldFileName"
:type="1"
@videoFn="videoFn"
@changeOldFileName="changeOldFileName"
/>
5. 效果图
官方文档地址: Qiniu-JavaScript-SDK