vue-simple-uploader使用实践
1、前言目前的element-ui在上传大文件时会出现上传失败的问题,项目希望实现大文件断点续传,秒传等功能。之前在TP项目下使用webuploader上传插件,文件服务器用PHP编写的。由于久不维护,决定使用vue-simple-uploader实现,文件服务器使用golang编写。2、安装npm install vue-simple-uploader --savemain.js引用:md5工具
·
1、前言
目前的element-ui在上传大文件时会出现上传失败的问题,项目希望实现大文件断点续传,秒传等功能。之前在TP项目下使用webuploader上传插件,文件服务器用PHP编写的。由于久不维护,决定使用vue-simple-uploader实现,文件服务器使用golang编写。
2、安装
npm install vue-simple-uploader --save
main.js引用:
md5工具安装:
npm install spark-md5 --save
在当前目录引用:
3、使用
<div
class="upload-box"
v-if="checkBtnMp4()"
>
<div>
<span class="title">上传视频</span>至多1个,不大于600M,支持格式:MP4
</div>
<uploader
ref="upload"
class="uploader-example"
:options="options"
:autoStart="true"
:file-status-text="statusText"
@file-success="success_video"
@file-added="filesAdded"
@file-progress="fileProgress"
@file-error="onFileError"
@file-removed="videoRemove"
>
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<uploader-btn
:single="true"
:attrs="attrs2"
>点击上传</uploader-btn>
</uploader-drop>
<uploader-list v-show="panelShow"></uploader-list>
</uploader>
<ul
class="el-upload-list el-upload-list--text success-video"
v-if="show_filename && fileListMp4"
>
<li
tabindex="0"
class="el-upload-list__item is-success"
v-for="(item, i) in fileListMp4"
:key="i"
>
<a class="el-upload-list__item-name">
<i class="el-icon-video-play"></i>
{{item.filename}}
</a>
<label class="el-upload-list__item-status-label">
<i class="el-icon-upload-success el-icon-circle-check"></i>
</label>
<i
class="el-icon-close"
@click="delMp4()"
></i>
</li>
</ul>
</div>
export default {
name: "XXX",
data() {
return {
isUploadOk: true, // 是否还有未上传完成的文件
// 视频
FileLimit: {
FileMaxSize: 600, // 允许上传的大小 单位(G)
FileFormat: ["mp4"], // 允许上传的格式
FileUnit: "M" // 单位
},
panelShow: true, // 展示上传panel
show_filename: true, //是否显示文件列表
fileListMp4: [], // 视频格式数据
uploadUrl: "", // 文件上传地址
uploadData: "", // 文件上传参数
options: {
target: url.uploadPath, // 上传地址
testChunks: false,
singleFile: true, // 启用单个文件上传。上传一个文件后,第二个文件将超过现有文件,第一个文件将被取消。
chunkSize: "1048576" * 1, //分块大小 单位(M)
//下面参数文件服务器验证用
query: {
//传参
UserId: localStorage.getItem("ms_userid"),
SessionKey: localStorage.getItem("ms_token"),
OS: 4,
PluginType: 1
}
},
//上传状态
statusText: {
success: "上传成功!",
error: "出错了!",
uploading: "上传中...",
paused: "等待中...",
waiting: "等待中..."
},
attrs2: {
accept: ".mp4" //允许上传的格式
}
};
}
4、上传流程
filesAdded:添加一个文件时的钩子。
progress:上传中的钩子。
onFileError:上传错误触发。
videoRemove:视频移除。
success_video:成功上传触发方法。
// 添加一个文件时触发
async filesAdded(file) {
var FileLimit = this.FileLimit;
const isFormat = this.checkExtensions(file.name, FileLimit.FileFormat); // 文件格式判断
if (!isFormat) {
file.ignored = true; // 过滤文件
file.cancel(); // 停止上传
return false;
}
// 文件大小判断
const isSize = this.checkSize(file.size);
if (!isSize) {
file.ignored = true; // 过滤文件
file.cancel(); // 停止上传
return false;
} else {
this.panelShow = true; // 展示上传panel
this.show_filename = false; // 不显示文件名
this.computeMD5(file); // md5验证
}
},
// 检查文件大小
checkSize(fileSize) {
var FileLimit = this.FileLimit;
var isSize = fileSize / 1024 / 1024 < FileLimit.FileMaxSize; // 单位(M)
if (!isSize) {
this.$message.warning(
" 文件大小不能大于" + FileLimit.FileMaxSize + FileLimit.FileUnit + "!"
);
return false;
}
return true;
},
// extensions 允许上传的格式
checkExtensions(fileName, extensions) {
var format = fileName
.split(".")
.pop()
.toLowerCase(); // 用户上传的文件格式
// 把允许上传文件格式的数组转为字符串
var s = extensions.join(",");
var exp = new RegExp(format);
if (!exp.test(extensions)) {
this.$message.warning("请上传 " + s + " 的格式!");
return false;
}
return true;
},
// 文件上传中触发
fileProgress(rootFile, file, chunk) {
// 判断上传是否在上传
if (file.isUploading()) {
this.isUploadOk = false; // 禁止上传
} else {
this.isUploadOk = true; // 允许上传
}
},
// 上传错误触发
onFileError(rootFile, file, response, chunk) {
this.$message({
message: "上传失败,请重新上传!",
type: "error"
});
},
// 校验MD5
computeMD5(file) {
let fileReader = new FileReader();
let time = new Date().getTime();
let blobSlice =
File.prototype.slice ||
File.prototype.mozSlice ||
File.prototype.webkitSlice;
let currentChunk = 0;
const chunkSize = 10 * 1024 * 1000;
let chunks = Math.ceil(file.size / chunkSize);
let spark = new SparkMD5.ArrayBuffer();
file.pause();
loadNext();
fileReader.onload = e => {
spark.append(e.target.result);
if (currentChunk < chunks) {
currentChunk++;
loadNext();
this.$nextTick(() => {});
} else {
let md5 = spark.end();
this.computeMD5Success(md5, file);
}
};
fileReader.onerror = function() {
this.error(`文件${file.name}读取出错,请检查该文件`);
file.cancel();
};
function loadNext() {
let start = currentChunk * chunkSize;
let end =
start + chunkSize >= file.size ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
}
},
// 验证成功
computeMD5Success(md5, file) {
file.uniqueIdentifier = api.randomString(32); //把md5值作为文件的识别码
file.resume(); //开始上传
},
// 视频移除
videoRemove(file, fileList) {
this.fileListMp4 = [];
},
// 成功上传触发方法
success_video: function(rootFile, file, response, chunk) {
var response = JSON.parse(response);
if (response.Result) {
const fileLists = [];
fileLists.push(response.Data);
this.fileList = fileLists;
} else {
this.$message.error(response.Errstr);
return false;
}
},
更多推荐
已为社区贡献1条内容
所有评论(0)