element-文件上传-自定义上传方式
这次主要写的是el-upload这个组件中的http-request钩子,首先来看一下官方的:
非常的简洁,简洁到完全看不懂了,简直了。
先展示一下我的成果,记得先把jquery,vue,element引入
这里实现了上传成功的回调和进度条的显示。失败的回调可以参考成功回调的方式写,差不多我就没写了。
var el_my_uploader = Vue.extend({
props: ["maxSize", "maxCount", "fileList", "UploadUrl", "accept", "drag", "multiple"],
template: '<div >' +
'<el-upload :action="UploadUrl" :limit="maxCount" :on-exceed="handleExceed" ' +
' :before-upload="beforeUpload" :file-list="uploadFiles" :accept="accept" ' +
' :on-preview="handlePreview" ' +
' :before-remove="beforeRemove" :drag="drag" :multiple="multiple"' +
' :on-success="handleSuccess" :http-request="handleUpload">' +
'<slot>' +
'<el-button size="small" type="primary">点击上传</el-button>' +
'</slot>' +
'<slot name="tip" slot="tip"></slot>' +
'</el-upload>' +
'</div>',
data: function() {
var obj = {
uploadFiles: [],
uploaderId: ''
}
return obj;
},
created: function() {
if (!this.fileList) {
this.fileList = [];
}
this.uploadFiles = this.fileList;
},
methods: {
handleExceed(files, fileList) {
// 上传数量超限
this.$message.warning(`当前限制选择 ${this.maxCount} 个文件`);
return false;
},
handlePreview(file) {
// 点击文件列表下载事件
if (file.state && file.state != 1) {
this.$message.warning(`文件${ file.name }正在上传,`);
return false;
} else {
if (file.url) {
window.open(file.url);
}
}
},
handleSuccess(res, file, fileList) {
// fileList 中file参数添加
for (let i = 0; i < fileList.length; i++) {
if (file.uid == fileList[i].uid) {
fileList[i].file = fileList[i].raw;
fileList[i].state = 1;
this.uploadFiles = fileList;
break;
}
}
// 是否绑定了on-success 方法
if (this.$listeners['on-success']) {
this.$emit("on-success", res, file, fileList);
} else {
this.$message.success(`文件${file.name}上传成功!`);
}
},
beforeRemove(file, fileList) {
// 删除前判断
if (file.status == 'success') {
this.$confirm(`确定移除 ${ file.name }?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
// 手动删除
let index = fileList.findIndex(fileItem => fileItem.uid === file.uid);
fileList.splice(index, 1);
this.fileList = fileList;
this.uploadFiles = fileList;
this.$message.success(`删除${ file.name }成功!`);
}).catch(function() {});
// 阻止其内部删除操作
return false;
}
},
beforeUpload(file) {
// return false 为取消上传,将触发beforeRemove
//文件大小判断
const size = file.size;
if (this.maxSize && this.maxSize != -1) {
if (size > this.maxSize) {
this.$message.warning('文件大小超出限制');
//取消本次上传
return false;
}
}
//文件数量判断
if (this.maxCount && this.maxCount != -1) {
if (this.uploadFiles.length + 1 > this.maxCount) {
this.$message.warning(`最多上传 ${this.maxCount} 个文件`);
//取消本次上传
return false;
}
}
// 文件重复上传判断
for (var i = 0; i < this.uploadFiles.length; i++) {
var f = this.uploadFiles[i];
if (f.file && f.file.name == file.name && f.file.size == file.size) {
this.$message.warning(`文件${ file.name }已经上传过了`);
//取消本次上传
return false;
}
}
return true;
},
handleUpload(params) {
const file = params.file;
var url = this.UploadUrl;
// 这里用params.action 其实也是一样的
// 可以自己向url里面加点参数,一定要按自己需求来重写请求发送过程,这里是我用的版本的阉割版,毕竟有些东西不好写出来
var formData = new FormData();
formData.append("file", file);
$.ajax({
url: url,
type: "POST",
data: formData,
dataType: "text",
processData: false, // 告诉jQuery不要去处理发送的数据
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
success: function(data) {
// 上传完成调用onSuccess方法
params.onSuccess(json);
},
xhr: function() { //在jquery函数中直接使用ajax的XMLHttpRequest对象
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 /
evt.total);
// console.log("正在提交."+percentComplete.toString() + '%'); //在控制台打印上传进度
// 这个是进度条,获取传输进度并调用
params.onProgress({
percent: percentComplete
});
}
}, false);
return xhr;
}
});
},
getValue() {
var result = [];
for (let i = 0; this.uploadFiles && i < this.uploadFiles.length; i++) {
let f = this.uploadFiles[i];
if (f.statue != 'success') {
this.$message.warning("图片未上传完成,请稍等");
return;
}
result.push({
id: f.id,
name: f.name,
size: f.file ? f.file.size : (f.size ? f.size : -1)
});
}
return result;
}
}
})
Vue.component('el_my_uploader', el_my_uploader);
还是代码来的清爽。
提示:
handleUpload(params) 中的这个参数建议直接打印出来看一下,里面有file,当前文件,有onSuccess,onError,onProgress三个方法。一个成功回调,一个失败回调,还有一个是显示进度条的。我这里使用的是ajax的方式,axios的有点点不同。
记住:如果你重写了http-request方法,这三个方法需要你手动调用的!!!,我这里偷懒点懒没有实现onError的调用,建议实现。
另外千万别手动去修改file-list的绑定对象,比如:上传时不要手动push一个对象,不然element会认为你已经上传完成的。
fileList的增删,element都会自己实现,你只需要按自己的需求在对应的回调方法(onSuccess等)里面去修改对象属性值就可以了。
来源:CSDN
作者:wilbur_xieyj
链接:https://blog.csdn.net/wilbur_xieyj/article/details/103901968