el-upload组件封装
- 重点在于使用http-request后,自带的进度条就被隐藏了,想要使用进度条,想要使用进度就得在axios请求调用onUploadProgress事件,调用onProgess事件,具体axios封装,看自己
this.$api({
url: '/planApi/drill/script/video/upload',
method: 'post',
data: files,
onUploadProgress: function (progressEvent) {
let percent = (progressEvent.loaded / progressEvent.total * 100).toFixed(0);
file.onProgress({percent: percent})
}
})
- 第二个重点就是,如果在文件上传中途,删掉文件,如果中止掉当前请求,在http-request请求中
updateFile(file){
const CancelToken = axios.CancelToken
const source = CancelToken.source()
this.$api({
cancelToken:source.token,
}).then(() => {
file.onSuccess()
---------
}).catch(() => {
const uid = file.file.uid
const idx = this.$refs.upload.uploadFiles.findIndex(item => item.uid === uid)
if (idx > 0) {
this.$refs.upload.uploadFiles.splice(idx, 1)
}
})
this.source.push({
source: source,
uid: file.file.uid
})
}
removeFile(file, i) {
if(file.status === 'uploading'){
this.source.forEach(item => {
if (item.uid === file.uid) {
item.source.cancel('您已取消了请求')
}
})
}
-----
}
- 贴上完整代码,而且还可以通过axios中的source来进行,在关闭页面时,取消全部请求的操作,或者在文件没有上传完成时的保存状态提示判断,这些都没有细去研究,这些都可以作为拓展功能
<template>
<div class="upload">
<el-upload
action="#"
ref="upload"
:http-request="updateFile"
:file-list="fileList"
:before-upload="beforeAvatarUpload"
:on-remove="removeFile"
>
<el-button size="small" type="primary">上传视频</el-button>
<div v-if="!warnDisabled" slot="tip" class="el-upload__tip" style="color: #fff">
1.支持flv, mp4, rmvb, swf,ogg,avi类型文件<br/>
2.上传文件不能超过1GB<br/>
3.等待出现√才是上传完成
</div>
</el-upload>
</div>
</template>
<script>
import axios from "axios";
export default {
name: 'tc-upload-video',
props: {
previewFileList: {
type: Array,
default: () => {
return []
}
},
warnDisabled: {
type: Boolean,
default: false
}
},
data() {
return {
fileList: [],
uploadFileList: [],
delFileList: [],
source: [],
requestArr: [],
isSuccess: true,
isShowCancel: false,
}
},
watch: {
previewFileList: {
handler: function (val) {
if (val.length) {
this.uploadFileList = JSON.parse(JSON.stringify(val))
this.fileList = val.map(item => {
return {
name: item.split('_')[1],
url: item,
}
})
this.delFileList = []
}else{
this.uploadFileList = []
this.fileList = []
this.delFileList = []
}
},
immediate: true
}
},
methods: {
async updateFile(file) {
let files = new FormData()
for (let a in file) {
files.append(a === 'raw' ? 'file' : a, file[a])
}
file.isUpload = true
const CancelToken = axios.CancelToken
const source = CancelToken.source()
this.$api({
url: '/planApi/drill/script/video/upload',
method: 'post',
data: files,
cancelToken:source.token,
onUploadProgress: function (progressEvent) {
let percent = (progressEvent.loaded / progressEvent.total * 100).toFixed(0);
file.onProgress({percent: percent})
}
}).then(res => {
file.onSuccess()
this.uploadFileList.push(res)
this.$emit('uploadList', this.uploadFileList)
}).catch(() => {
const uid = file.file.uid
const idx = this.$refs.upload.uploadFiles.findIndex(item => item.uid === uid)
if (idx > 0) {
this.$refs.upload.uploadFiles.splice(idx, 1)
}
})
this.source.push({
source: source,
uid: file.file.uid
})
this.requestArr.push(source)
},
beforeAvatarUpload(file) {
const isLt50M = file.size / 1024 / 1024 < 1000;
if (!isLt50M) {
this.$message.warning("上传文件大小不能超过 1GB!");
return false;
}
const validFileType = this.validateVideoType(file.name)
if (!validFileType) {
this.$message.error('文件格式错误!')
}
return validFileType
},
validateVideoType(fileName) {
fileName = fileName.toLowerCase()
let fileLimitType = ['flv', 'mp4', 'rmvb', 'swf', 'ogg', 'avi']
for (let i = 0, len = fileLimitType.length; i < len; i++) {
if (fileName.endsWith(fileLimitType[i])) {
return true
}
}
return false
},
removeFile(file, i) {
if(file.status === 'uploading'){
this.source.forEach(item => {
if (item.uid === file.uid) {
item.source.cancel('您已取消了请求')
}
})
}
let fileObj = {}
this.uploadFileList.map((item, index) => {
if (item.split('_').includes(file.name)) {
fileObj = {
filename: item,
index: index
}
}
})
if (fileObj.filename) {
this.uploadFileList.splice(fileObj.index, 1)
this.$emit('uploadList', this.uploadFileList)
this.delFileList.push(fileObj)
}
},
handleDelFileList() {
this.delFileList?.length && this.delFileList.map(fileObj => {
this.$api.delete(`/planApi/drill/script/video/delete?filename=${fileObj.filename}`)
})
},
}
}
</script>
<style scoped lang="scss">
.upload {
margin: 25px 0;
max-width: 500px;
.el-upload__tip {
color: #fff
}
& ::v-deep .el-upload-list__item:hover {
background: transparent;
}
}
.warnUpload {
margin-top: -64px;
& ::v-deep ul {
padding-left: 0;
}
}
</style>