0%

File Upload

// 调用上传功能
handleUpClick() {
this.uploadFinished // 维护一个上传状态,上传过程中禁用上传按钮
? this.$refs.input.click()
console.warn(‘请等待当前文件全部上传完成’);
},
handleFiles(e) {
const files = e?.target?.files;
this.readFiles(files);
},

// 上传之前将文件处理为对象
readFiles(files) {
if (!files || files.length <= 0) {
return;
}
for (const file of files) {
const url = window.URL.createObjectURL(file);
const obj = {
title: file.name.replace(/(.[^.]*$)|[_]/gi, ‘’), // 去掉文件后缀
url,
file,
fileType: file.fileType,
status: 0, // 状态 -> 0 等待中,1 完成, 2  正在上传,3 上传失败
percent: 0, // 上传进度
};
// 提前在 data 中定义 list,用来保存需要上传的文件
this.list.push(obj);
}
// 在 data 中定义 startIndex 初始值为 0,上传完成后更新,用于追加上传文件
this.startUpload(this.startIndex);
},

//  上传前需要校验文件
checkFile(index) {
const file = this.list[index];

// 如果文件不存在,即全部文件上传完成 
if (!file) {
this.uploadFinished = true;   // 上传完成,向父组件抛出 success 事件
this.$emit(‘success’, this.list);
// 清空上传控件中的值,保证 change 事件能正常触发
this.$refs.input.value = null; this.startIndex = index > 1 ? index - 1 : 0;
return false;
}

// 校验是否已上传
if (${file.status} === “1”) {
this.startUpload(++index);
return false;
}

// 校验文件大小
if (this.maxSize && file.file && file.file.size >= this.maxSize) {
this.startUpload(++index);
return false;
}

return true;
},// 上传单个文件
startUpload(index) {
if (!this.checkFile(index)) { return; }

// 开始上传,维护上传状态
this.uploadFinished = false;
const file = this.list[index].file;
const fileObj = this.list[index];

// 创建 formData 用于提交
const data = new FormData();
data.append(‘userfile’, file);
axios({
url: this.url, // 上传接口,由 props 传入
method: ‘post’,
data,
withCredentials: true,
cancelToken: this.source.token, // 用于取消接口请求
// 进度条
onUploadProgress: e => {
if (fileObj.status === 1) { return; } // 已上传
// 限定最大值为 99%
const p = parseInt((e.loaded / e.total) * 99);
if (e.total) {
fileObj.status = 2; // 正在上传
fileObj.percent = p; // 更新上传进度
} else {
fileObj.status = 3; // 上传失败
}
},
})
.then(response => {
if (${response.code} === “200”) {
fileObj.status = 1;
fileObj.percent = 100;
} else {
fileObj.status = 3;
}
})
.catch(e => {
fileObj.status = 3;
})
.finally(e => {
this.startUpload(++index);
});
// 上传完成
},

data: () => ({
list: [], // 已选择的文件对象
uploadFinished: true, // 上传状态
startIndex: 0, // 开始上传的下标,用于追加文件
source: axios.CancelToken.source(), // axios 取消请求
}),

reset() { // 重置
this.list = [];
this.source.cancel();
this.startIndex = 0;
this.uploadFinished = true;
this.$refs.input && (this.$refs.input.value = null);
},

、拖拽上传

bindEvents() {
const dropbox = this.$refs.pickerArea;
// 防止重复绑定事件,需要在 data 中初始化 bindDrop 为 false
if (!dropbox || this.bindDrop) { return }
// 绑定拖拽事件,在组件销毁时解绑
dropbox.addEventListener(“drop”, this.handleDrop, false);
dropbox.addEventListener(“dragleave”, this.handleDragLeave);
dropbox.addEventListener(“dragover”, this.handleDragOver);
this.bindDrop = true;
},
// 拖拽到上传区域
handleDragOver(e) {
e.stopPropagation();
e.preventDefault();
this.dragging = true;
},
// 离开上传区域
handleDragLeave(e) {
e.stopPropagation();
e.preventDefault();
this.dragging = false;
},
// 拖拽结束
handleDrop(e) {
e.stopPropagation();
e.preventDefault();
this.dragging = false;
const files = e.dataTransfer.files; // 调用 组件的上传功能
this.$refs.uploadBtn && this.$refs.uploadBtn.readFiles(files);
},

beforeDestroy() {
// 组件销毁前解绑拖拽事件
try {
const dropbox = this.$refs.pickerArea;
dropbox.removeEventListener(“drop”, this.handleDrop);
dropbox.removeEventListener(“dragleave”, this.handleDragLeave);
dropbox.removeEventListener(“dragover”, this.handleDragOver);
this.bindDrop = false;
} catch (e) {}
},