element/packages/upload/src/upload.vue

200 lines
4.5 KiB
Vue
Raw Normal View History

2016-07-27 06:15:02 +00:00
<script>
2016-08-20 10:27:37 +00:00
import ajax from './ajax';
2017-02-12 16:44:57 +00:00
import UploadDragger from './upload-dragger.vue';
2016-07-27 06:15:02 +00:00
export default {
2017-05-02 04:46:57 +00:00
inject: ['uploader'],
2017-02-12 16:44:57 +00:00
components: {
UploadDragger
},
2016-07-27 06:15:02 +00:00
props: {
2016-08-20 10:27:37 +00:00
type: String,
2016-07-27 06:15:02 +00:00
action: {
type: String,
required: true
},
name: {
type: String,
default: 'file'
},
2016-10-12 02:31:50 +00:00
data: Object,
2016-09-02 10:11:45 +00:00
headers: Object,
2016-08-20 10:27:37 +00:00
withCredentials: Boolean,
multiple: Boolean,
2016-07-27 06:15:02 +00:00
accept: String,
2016-08-20 10:27:37 +00:00
onStart: Function,
onProgress: Function,
onSuccess: Function,
onError: Function,
beforeUpload: Function,
2017-02-12 16:44:57 +00:00
drag: Boolean,
2016-08-20 10:27:37 +00:00
onPreview: {
type: Function,
default: function() {}
2016-07-27 06:15:02 +00:00
},
2016-08-20 10:27:37 +00:00
onRemove: {
type: Function,
default: function() {}
2017-02-08 11:05:34 +00:00
},
fileList: Array,
2017-02-12 16:44:57 +00:00
autoUpload: Boolean,
2017-03-09 06:30:00 +00:00
listType: String,
httpRequest: {
type: Function,
default: ajax
2017-04-21 03:57:30 +00:00
},
disabled: Boolean,
limit: Number,
onExceed: Function
2016-07-27 06:15:02 +00:00
},
data() {
return {
2017-05-02 04:46:57 +00:00
mouseover: false,
reqs: {}
2016-07-27 06:15:02 +00:00
};
},
methods: {
isImage(str) {
return str.indexOf('image') !== -1;
},
2016-08-20 10:27:37 +00:00
handleChange(ev) {
const files = ev.target.files;
2017-02-08 11:05:34 +00:00
if (!files) return;
2016-08-20 10:27:37 +00:00
this.uploadFiles(files);
2016-07-27 06:15:02 +00:00
},
2016-08-20 10:27:37 +00:00
uploadFiles(files) {
if (this.limit && this.fileList.length + files.length > this.limit) {
this.onExceed && this.onExceed(files, this.fileList);
return;
}
2016-08-20 10:27:37 +00:00
let postFiles = Array.prototype.slice.call(files);
if (!this.multiple) { postFiles = postFiles.slice(0, 1); }
if (postFiles.length === 0) { return; }
2016-07-27 06:15:02 +00:00
2017-02-08 11:05:34 +00:00
postFiles.forEach(rawFile => {
2017-03-20 04:45:00 +00:00
this.onStart(rawFile);
if (this.autoUpload) this.upload(rawFile);
2016-07-27 06:15:02 +00:00
});
},
2017-02-08 11:05:34 +00:00
upload(rawFile, file) {
this.$refs.input.value = null;
2016-08-20 10:27:37 +00:00
if (!this.beforeUpload) {
2017-02-08 11:05:34 +00:00
return this.post(rawFile);
2016-08-20 10:27:37 +00:00
}
2016-07-27 06:15:02 +00:00
2017-02-08 11:05:34 +00:00
const before = this.beforeUpload(rawFile);
2016-08-20 10:27:37 +00:00
if (before && before.then) {
before.then(processedFile => {
const fileType = Object.prototype.toString.call(processedFile);
if (fileType === '[object File]' || fileType === '[object Blob]') {
2016-08-20 10:27:37 +00:00
this.post(processedFile);
} else {
2017-02-08 11:05:34 +00:00
this.post(rawFile);
2016-08-20 10:27:37 +00:00
}
}, () => {
2017-09-18 04:37:32 +00:00
this.onRemove(null, rawFile);
2016-08-20 10:27:37 +00:00
});
} else if (before !== false) {
2017-02-08 11:05:34 +00:00
this.post(rawFile);
2016-08-20 10:27:37 +00:00
} else {
2017-09-18 04:37:32 +00:00
this.onRemove(null, rawFile);
2016-08-20 10:27:37 +00:00
}
2016-07-27 06:15:02 +00:00
},
2017-05-02 04:46:57 +00:00
abort(file) {
const { reqs } = this;
if (file) {
let uid = file;
if (file.uid) uid = file.uid;
if (reqs[uid]) {
reqs[uid].abort();
}
} else {
Object.keys(reqs).forEach((uid) => {
if (reqs[uid]) reqs[uid].abort();
delete reqs[uid];
});
}
},
2017-02-08 11:05:34 +00:00
post(rawFile) {
2017-05-02 04:46:57 +00:00
const { uid } = rawFile;
const options = {
2016-08-20 10:27:37 +00:00
headers: this.headers,
withCredentials: this.withCredentials,
2017-02-08 11:05:34 +00:00
file: rawFile,
2016-10-12 02:31:50 +00:00
data: this.data,
2016-08-20 10:27:37 +00:00
filename: this.name,
action: this.action,
2016-08-20 10:27:37 +00:00
onProgress: e => {
2017-02-08 11:05:34 +00:00
this.onProgress(e, rawFile);
2016-08-20 10:27:37 +00:00
},
onSuccess: res => {
2017-02-08 11:05:34 +00:00
this.onSuccess(res, rawFile);
2017-05-02 04:46:57 +00:00
delete this.reqs[uid];
2016-08-20 10:27:37 +00:00
},
2017-02-14 16:35:34 +00:00
onError: err => {
this.onError(err, rawFile);
2017-05-02 04:46:57 +00:00
delete this.reqs[uid];
2016-08-20 10:27:37 +00:00
}
};
2017-05-02 04:46:57 +00:00
const req = this.httpRequest(options);
this.reqs[uid] = req;
if (req && req.then) {
req.then(options.onSuccess, options.onError);
}
2016-07-27 06:15:02 +00:00
},
2016-09-06 17:15:39 +00:00
handleClick() {
2017-04-21 03:57:30 +00:00
if (!this.disabled) {
2017-07-05 09:18:10 +00:00
this.$refs.input.value = null;
2017-04-21 03:57:30 +00:00
this.$refs.input.click();
}
},
handleKeydown(e) {
if (e.keyCode === 13 || e.keyCode === 32) {
this.handleClick();
}
2016-07-27 06:15:02 +00:00
}
2017-02-08 11:05:34 +00:00
},
render(h) {
let {
handleClick,
2017-02-12 16:44:57 +00:00
drag,
name,
2017-02-08 11:05:34 +00:00
handleChange,
multiple,
accept,
2017-02-12 16:44:57 +00:00
listType,
2017-04-21 03:57:30 +00:00
uploadFiles,
disabled,
handleKeydown
2017-02-08 11:05:34 +00:00
} = this;
const data = {
class: {
'el-upload': true
},
on: {
click: handleClick,
keydown: handleKeydown
2017-02-08 11:05:34 +00:00
}
};
2017-02-12 16:44:57 +00:00
data.class[`el-upload--${listType}`] = true;
2017-02-08 11:05:34 +00:00
return (
<div {...data} tabindex="0" >
2017-02-08 11:05:34 +00:00
{
2017-02-12 16:44:57 +00:00
drag
2017-04-21 03:57:30 +00:00
? <upload-dragger disabled={disabled} on-file={uploadFiles}>{this.$slots.default}</upload-dragger>
2017-02-08 11:05:34 +00:00
: this.$slots.default
}
<input class="el-upload__input" type="file" ref="input" name={name} on-change={handleChange} multiple={multiple} accept={accept}></input>
2017-02-08 11:05:34 +00:00
</div>
);
2016-07-27 06:15:02 +00:00
}
};
</script>