ivew 的ajax,iView-Upload组件分析
源碼分析
xhr相關(guān)知識點
Ajax要點分析
拖拽事件以及粘貼事件
具體實現(xiàn)
總結(jié)
xhr相關(guān)知識點
XMLHttpRequest.upload 屬性返回一個 XMLHttpRequestUpload對象,用來表示上傳的進度。
通過onprogress屬性進行監(jiān)聽,是在 XMLHttpRequest 完成之前周期性調(diào)用的函數(shù)。
xhr.upload.onprogress?=?function?progress(e)?{
event.loaded 已傳輸?shù)臄?shù)據(jù)量
event.total 總共的數(shù)據(jù)量
if?(e.total?>?0)?{
e.percent?=?e.loaded?/?e.total?*?100;
}
};
復制代碼
XMLHttpRequestEventTarget.onload 是 XMLHttpRequest 請求成功完成時調(diào)用的函數(shù)。使用該屬性使得判斷更加簡單
使用onreadystatechange屬性
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE) {//當前狀態(tài)碼為'DONE'(4),表示下載操作已完成
console.log(xhr.responseText)
}
}
使用onload屬性
xhr.onload = function onload() {
...
};
復制代碼
HTTP 響應狀態(tài)代碼指示特定 HTTP 請求是否已成功完成。
信息響應(100-199)
成功響應(200-299)
重定向(300-399)
客戶端錯誤(400-499)
服務(wù)器錯誤(500-599)
Ajax的封裝
源碼鏈接 github.com/ElemeFE/ele…
該源碼不考慮IE低版本的情況,即ActiveXObject不在考慮范圍。
創(chuàng)建一個FormData對象,將相關(guān)的數(shù)據(jù)進行添加,包括文件
const formData = new FormData();
if (option.data) {
Object.keys(option.data).map(key => {
formData.append(key, option.data[key]); //通過遍歷添加新的屬性值
});
}
formData.append(option.filename, option.file); //添加文件
復制代碼
狀態(tài)碼status小于200或大于等于300的狀態(tài)進行錯誤提示
xhr.onload = function onload() {
if (xhr.status < 200 || xhr.status >= 300) {
return option.onError(getError(action, option, xhr), getBody(xhr));
}
};
復制代碼
設(shè)置請求頭信息,忽略headers的繼承屬性同時值不能為null;這里進行headers.hasOwnProperty(item)的判斷,可以避免這種情況:請求 中的headers繼承共用headers中的請求頭信息。
const headers = option.headers || {};
for (let item in headers) {
if (headers.hasOwnProperty(item) && headers[item] !== null) {
xhr.setRequestHeader(item, headers[item]);
}
}
復制代碼
拖拽事件以及粘貼事件
拖拽事件中,對需要拖動的元素賦予draggable屬性;在釋放位置所在的元素上使用drop事件,同時在拖動的元素上dragover阻止默認行為以啟用drop
document.addEventListener("dragover", function( event ) {
// 阻止默認動作以啟用drop
event.preventDefault();
}, false);
復制代碼
利用DataTransfer這個對象可以在拖拽過程中傳遞數(shù)據(jù);涉及Upload組件的屬性: e.DataTransfer.files在拖動操作中表示文件列表,是一個類數(shù)組
dragevent.dataTransfer.setData("text", xxx); //拖動時設(shè)置數(shù)據(jù)
dropevent.dataTransfer.getData("text"); //釋放時獲取數(shù)據(jù)
復制代碼
粘貼事件paste: 事件處理程序可以通過調(diào)用事件的?clipboardData?屬性上的?getData()訪問剪貼板內(nèi)容;涉及Upload組件的屬性: e.clipboardData.files獲取到粘貼的文件列表,同樣也是一個類數(shù)組
event.clipboardData.getData()
復制代碼
具體實現(xiàn)
Upload組件提供了3種選擇文件的方式: 點擊,拖拽和粘貼;點擊的方式通過調(diào)用原生的input點擊事件,監(jiān)聽input上的change事件獲取到文件列表;拖拽和粘貼的方式則是通過事件drop,paste直接獲取到文件列表;由于在點擊方式中使用的是點擊input實現(xiàn)的,所以在單選時彈出文件選擇框時已經(jīng)限制只能選中一個,但是拖拽和粘貼在單選時仍然可以選擇多個文件,所以需要進行過濾,保證單選模式下只能存在一個文件。校驗文件格式及大小,符合條件就開始發(fā)起請求,為每個文件添加屬性(uid,percentage,status...),最后,通過回調(diào)函數(shù)獲取上傳進度,成功請求,失敗請求相關(guān)參數(shù)。
事件的處理,通過動態(tài)觸發(fā)input元素的click事件,值得注意的是選擇完成后,需要手動設(shè)置value值為空,保證下次選擇同一文件還會觸發(fā)input的change事件
//點擊方式
handleClick () {
...
this.$refs.input.click();
},
handleChange (e) {
const files = e.target.files;
...
this.$refs.input.value = null;
},
//拖拽方式
onDrop (e) {
this.uploadFiles(e.dataTransfer.files);
},
//粘貼方式
handlePaste (e) {
this.uploadFiles(e.clipboardData.files);
}
復制代碼
對文件列表初始化
uploadFiles (files) {
let postFiles = Array.prototype.slice.call(files); // 類數(shù)組轉(zhuǎn)數(shù)組
if (!this.multiple) postFiles = postFiles.slice(0, 1); //單選下保證所有的文件列表只有一條數(shù)據(jù)
if (postFiles.length === 0) return;
postFiles.forEach(file => {
this.upload(file);
});
},
復制代碼
創(chuàng)建每個文件對應的數(shù)據(jù)集合,并且發(fā)起請求,通過值傳遞為每個數(shù)據(jù)集合添加uid
post (file) {
this.handleStart(file);
ajax({
...,
onProgress: e => {
this.handleProgress(e, file);
},
onSuccess: res => {
this.handleSuccess(res, file);
},
onError: (err, response) => {
this.handleError(err, response, file);
}
});
}
復制代碼
請求回調(diào)函數(shù),為對應的處理函數(shù)返回值
handleProgress (e, file) {
const _file = this.getFile(file); //獲取到文件的詳細信息
this.onProgress(e, _file, this.fileList); //事件,當前文件,文件列表
_file.percentage = e.percent || 0; //進度
}
handleSuccess (res, file) {
const _file = this.getFile(file);
if (_file) {
_file.status = 'finished'; //更新狀態(tài)
_file.response = res;
this.onSuccess(res, _file, this.fileList);
}
},
handleError (err, response, file) {
const _file = this.getFile(file);
const fileList = this.fileList;
_file.status = 'fail'; //更新狀態(tài)
fileList.splice(fileList.indexOf(_file), 1);
this.onError(err, response, file);
},
復制代碼
總結(jié)
Upload組件涉及的API較廣,需要了解;還有一些概念,比如代碼的值傳遞,基于引用類型的復制,靈活地為每個文件集合添加uid屬性,同時又能快捷方便刪除項。
總結(jié)
以上是生活随笔為你收集整理的ivew 的ajax,iView-Upload组件分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言求最多啤酒数,C语言,算法、动态规
- 下一篇: javawed商店商品结算_微信小商店搭