el-upload中单文件多文件上传,有表格进度条 也可以直接看这篇文章: blog.csdn.net/l976425836/… 作者大大写的很好
<el-upload
ref="uploadMutiple"
action=""
:show-file-list="false"
:multiple="true"
:before-upload="beforeUpload"
style="float: right;"
>
<el-button size="mini" type="primary">选择文件</el-button>
</el-upload>
<el-table
:data="uploadFilesList"
ref="singleTable"
highlight-current-row
style="width: 100%">
<el-table-column
type="index"
label="序号"
align="center"
>
</el-table-column>
<el-table-column
prop="videoName"
label="视频名称"
show-overflow-tooltip
align="center">
</el-table-column>
<el-table-column prop="videoName" label="上传状态" width="300">
<template slot-scope="scope">
<span>{{scope.row.status}}</span>
</template>
</el-table-column>
<el-table-column label="上传进度" width="300">
<template slot-scope="scope">
<el-progress :percentage="scope.row.progress" />
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
v-if="scope.row.status !== '上传失败'"
@click="reView(scope.row)">预览</el-button>
<el-button
size="mini"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog
:visible.sync="innerVisible"
v-el-drag-dialog
:modal="false"
:close-on-click-modal="false"
:show-close="false"
width="55%"
class="videoPage"
>
<div slot="title">
<el-row :gutter="20">
<el-col :span="24">
<span class="backContent">{{ vName }}</span>
<span class="close" style="color: #909399" @click="handleClose">
<i class="el-dialog__close el-icon el-icon-close"></i>
</span>
</el-col>
</el-row>
</div>
<div class="video_stream">
<div id="videoBackOne"></div>
</div>
</el-dialog>
// 实现的方法
beforeUpload(file) {
const isMP4 = file.type === 'video/mp4';
const isMP3 = file.type === 'audio/mp3';
const isLt = file.size / 1024 / 1024 < this.fileLtSize
if (!isMP4 && !isMP3) {
this.$message.error('上传文件只能是 MP4 或 MP3 格式!');
return false; // 文件类型不正确,阻止上传
}
if (!isLt) {
this.$message.error('上传视频文件大小不能超过' + this.fileLtSize + 'MB!')
return false; // 文件大小超出限制,阻止上传
}
const fileObj = {
videoName: file.name,
id: '',
progress: 0,
videoUrl: file.fileUrl,
status: '上传中'
};
this.uploadFilesList.push(fileObj);
this.httpRequest(fileObj, file);
return false; // 阻止默认上传行为
},
async httpRequest(fileObj, file, callback) {
this.uploadLoading = true
let formData = new FormData();
formData.append('files', file)
const reqConfig = {
headers: {
// 根据后台接口去写自己的请求头
},
// 获取上传进度
onUploadProgress: (progressEvent) => {
const progress = (progressEvent.loaded / progressEvent.total * 100) | 0;
this.$set(fileObj, 'progress', progress); // 更新进度
}
};
this.$axios.post(后台接口, formData, reqConfig).then((res) => {
if(res.status === 200) { // 这个具体看后台接口返回的结果
const videoList = res.data.data.videoList
if(videoList.length > 0) {
// 假设每个文件的上传状态都在 videoFiles 数组中
// 唯一标识这个,如果有别的更好的,根据文件名去,是因为新追加的没有id,可以拿到uid,但是后台返回的数据里面,没有uid。具体看后台返回的数据
const fileStatus = videoList.find(f => f.fileName === fileObj.videoName);
if (fileStatus && fileStatus.uploadStatus == '上传成功') {
// 如果后台返回上传成功,则更新状态,需要更新全部数据,我一开始只更新了进度和状态,导致预览和删除功能失效。
this.$set(fileObj, 'progress', 100);
this.$set(fileObj, 'videoName', fileStatus.fileName);
this.$set(fileObj, 'videoUrl', fileStatus.fileUrl);
this.$set(fileObj, 'status', fileStatus.uploadStatus);
this.$set(fileObj, 'id', fileStatus.id);
} else {
// 如果后台返回的不是上传成功,则视为失败
this.$set(fileObj, 'progress', 0);
this.$set(fileObj, 'status', '上传失败');
}
} else {
// 如果响应中没有 videoFiles 或其长度为0,也视为失败
this.$set(fileObj, 'progress', 0);
this.$set(fileObj, 'status', '上传失败');
}
} else {
// 如果响应中没有 videoFiles 或其长度为0,也视为失败
this.$set(fileObj, 'progress', 0);
this.$set(fileObj, 'status', '上传失败');
}
}).catch(() => { // 失败状态
// 捕获到错误,更新状态为上传失败
this.$set(fileObj, 'progress', 0);
this.$set(fileObj, 'status', '上传失败');
// 可以在这里处理错误,例如打印错误日志或显示错误信息
console.error('上传失败');
})
},
// 预览和删除也写一下吧,就当是提醒自己了,实现方法,我应该是已经写过了播放器的那个,但是发现在后续做的过程中,播放器还是会出问题
// 预览
reView(row) {
console.log('播放视频', row);
this.vName = row.videoName
this.innerVisible = true;
this.initVideoBack(row.videoUrl)
},
// 初始化播放器 导致视频播放器显示不出来的问题主要是没有高度
initVideoBack(currentUrl) {
if (this.player) {
this.player.destroy()
this.player = null
}
this.$nextTick(() => {
this.player = new Player({
id: 'videoBackOne',
url: currentUrl,
// autoplay: true,
height: '90%',
width: '100%',
videoAttributes: {
crossOrigin: 'anonymous'
}
});
this.player.on(Events.ERROR, (error) => {
console.log(error) // xgplayer 中的 Errors 对象
})
})
},
// 删除
handleDelete(row) {
// 判断是否有 row.id,如果没有则直接在前端删除,否则调用接口删除
if (row.id) {
// 调用接口删除服务器上的数据
this.deleteFromServer(row);
} else {
// 直接在前端删除
this.deleteFromFrontEnd(row);
}
},
// 这个删除可能有问题,但是一般正常的操作,文件名不能是一样的
deleteFromFrontEnd(row) {
// 在前端删除操作
// 找到要删除的元素索引
const index = this.uploadFilesList.findIndex(file => file.videoName === row.videoName);
this.$confirm(`确定删除剧集【${row.videoName}】吗?`, '提交', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'success'
}).then(() => {
if (index !== -1) {
// 从列表中移除元素
this.uploadFilesList.splice(index, 1);
this.$message({
message: '删除成功!',
type: 'success'
});
}
})
},