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等)裏面去修改對象屬性值就可以了。