uid];
});
}
},
//上传文件过程的方法
post(rawFile) {
const { uid } = rawFile;
const options = {
headers: this.headers,
withCredentials: this.withCredentials,
file: rawFile,
data: this.data,
filename: this.name,
action: this.action,
onProgress: e => { //文件上传时的钩子函数
this.onProgress(e, rawFile);
},
onSuccess: res => { //文件上传成功的钩子函数
//上传成功调用onSuccess方法,即index.vue中的handleSuccess方法
this.onSuccess(res, rawFile);
delete this.reqs[uid];
},
onError: err => { //文件上传失败的钩子函数
this.onError(err, rawFile);
delete this.reqs[uid];
}
};
//httpRequest可以自定义上传文件,如果没有定义,默认通过ajax文件中的方法上传
const req = this.httpRequest(options);
this.reqs[uid] = req;
if (req && req.then) {
req.then(options.onSuccess, options.onError);
}
},
handleClick() {
//点击组件时调用input的click方法
if (!this.disabled) {
this.$refs.input.value = null;
this.$refs.input.click();
}
},
handleKeydown(e) {
if (e.target !== e.currentTarget) return;
//如果当前按下的是回车键和空格键,调用handleClick事件
if (e.keyCode === 13 || e.keyCode === 32) {
this.handleClick();
}
}
},
render(h) {
let {
handleClick,
drag,
name,
handleChange,
multiple,
accept,
listType,
uploadFiles,
disabled,
handleKeydown
} = this;
const data = {
class: {
'el-upload': true
},
on: {
click: handleClick,
keydown: handleKeydown
}
};
data.class[`el-upload--${listType}`] = true;
return (
//判断是否允许拖拽,允许的话显示upload-dragger组件,不允许就显示所有插槽中的节点
<div {...data} tabindex="0" >
{
drag
? <upload-dragger disabled={disabled} on-file={uploadFiles}>{this.$slots.default}</upload-dragger>
: this.$slots.default
}
<input class="el-upload__input" type="file" ref="input" name={name} on-change={handleChange} multiple={multiple} accept={accept}></input>
</div>
);
}
};
</script>
ajax.js
function getError(action, option, xhr) {
let msg;
if (xhr.response) {
msg = `${xhr.response.error || xhr.response}`;
} else if (xhr.responseText) {
msg = `${xhr.responseText}`;
} else {
msg = `fail to post ${action} ${xhr.status}`;
}
const err = new Error(msg);
err.status = xhr.status;
err.method = 'post';
err.url = action;
return err;
}
function getBody(xhr) {
const text = xhr.responseText || xhr.response;
if (!text) {
return text;
}
try {
return JSON.parse(text);
} catch (e) {
return text;
}
}
//默认的上传文件的方法
export default function upload(option) {
//XMLHttpRequest 对象用于在后台与服务器交换数据。
if (typeof XMLHttpRequest === 'undefined') {
return;
}
//创建XMLHttpRequest对象
const xhr = new XMLHttpRequest();
const action = option.action; //上传的地址
//XMLHttpRequest.upload 属性返回一个 XMLHttpRequestUpload对象,用来表示上传的进度。这个对象是不透明的,但是作为一个XMLHttpRequestEventTarget,可以通过对其绑定事件来追踪它的进度。
if (xhr.upload) {
//上传进度调用方法,上传过程中会频繁调用该方法
xhr.upload.onprogress = function progress(e) {
if (e.total > 0) {
// e.total是需要传输的总字节,e.loaded是已经传输的字节
e.percent = e.loaded / e.total * 100;
}
//调文件上传时的钩子函数
option.onProgress(e);
};
}
// 创建一个FormData 对象
const formData = new FormData();
//用户设置了上传时附带的额外参数时
if (option.data) {
Object.keys(option.data).forEach(key => {
// 添加一个新值到 formData 对象内的一个已存在的键中,如果键不存在则会添加该键。
formData.append(key, option.data[key]);
});
}
formData.append(option.filename, option.file, option.file.name);
//请求出错
xhr.onerror = function error(e) {
option.onError(e);
|