212 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
| <script>
 | |
| import ajax from './ajax';
 | |
| import UploadDragger from './upload-dragger.vue';
 | |
| 
 | |
| export default {
 | |
|   inject: ['uploader'],
 | |
|   components: {
 | |
|     UploadDragger
 | |
|   },
 | |
|   props: {
 | |
|     type: String,
 | |
|     action: {
 | |
|       type: String,
 | |
|       required: true
 | |
|     },
 | |
|     name: {
 | |
|       type: String,
 | |
|       default: 'file'
 | |
|     },
 | |
|     data: Object,
 | |
|     headers: Object,
 | |
|     withCredentials: Boolean,
 | |
|     multiple: Boolean,
 | |
|     accept: String,
 | |
|     onStart: Function,
 | |
|     onProgress: Function,
 | |
|     onSuccess: Function,
 | |
|     onError: Function,
 | |
|     beforeUpload: Function,
 | |
|     drag: Boolean,
 | |
|     onPreview: {
 | |
|       type: Function,
 | |
|       default: function() {}
 | |
|     },
 | |
|     onRemove: {
 | |
|       type: Function,
 | |
|       default: function() {}
 | |
|     },
 | |
|     fileList: Array,
 | |
|     autoUpload: Boolean,
 | |
|     listType: String,
 | |
|     httpRequest: {
 | |
|       type: Function,
 | |
|       default: ajax
 | |
|     },
 | |
|     disabled: Boolean,
 | |
|     limit: Number,
 | |
|     onExceed: Function
 | |
|   },
 | |
| 
 | |
|   data() {
 | |
|     return {
 | |
|       mouseover: false,
 | |
|       reqs: {}
 | |
|     };
 | |
|   },
 | |
| 
 | |
|   methods: {
 | |
|     isImage(str) {
 | |
|       return str.indexOf('image') !== -1;
 | |
|     },
 | |
|     handleChange(ev) {
 | |
|       const files = ev.target.files;
 | |
| 
 | |
|       if (!files) return;
 | |
|       this.uploadFiles(files);
 | |
|     },
 | |
|     uploadFiles(files) {
 | |
|       if (this.limit && this.fileList.length + files.length > this.limit) {
 | |
|         this.onExceed && this.onExceed(files, this.fileList);
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       let postFiles = Array.prototype.slice.call(files);
 | |
|       if (!this.multiple) { postFiles = postFiles.slice(0, 1); }
 | |
| 
 | |
|       if (postFiles.length === 0) { return; }
 | |
| 
 | |
|       postFiles.forEach(rawFile => {
 | |
|         this.onStart(rawFile);
 | |
|         if (this.autoUpload) this.upload(rawFile);
 | |
|       });
 | |
|     },
 | |
|     upload(rawFile) {
 | |
|       this.$refs.input.value = null;
 | |
| 
 | |
|       if (!this.beforeUpload) {
 | |
|         return this.post(rawFile);
 | |
|       }
 | |
| 
 | |
|       const before = this.beforeUpload(rawFile);
 | |
|       if (before && before.then) {
 | |
|         before.then(processedFile => {
 | |
|           const fileType = Object.prototype.toString.call(processedFile);
 | |
| 
 | |
|           if (fileType === '[object File]' || fileType === '[object Blob]') {
 | |
|             if (fileType === '[object Blob]') {
 | |
|               processedFile = new File([processedFile], rawFile.name, {
 | |
|                 type: rawFile.type
 | |
|               });
 | |
|             }
 | |
|             for (const p in rawFile) {
 | |
|               if (rawFile.hasOwnProperty(p)) {
 | |
|                 processedFile[p] = rawFile[p];
 | |
|               }
 | |
|             }
 | |
|             this.post(processedFile);
 | |
|           } else {
 | |
|             this.post(rawFile);
 | |
|           }
 | |
|         }, () => {
 | |
|           this.onRemove(null, rawFile);
 | |
|         });
 | |
|       } else if (before !== false) {
 | |
|         this.post(rawFile);
 | |
|       } else {
 | |
|         this.onRemove(null, rawFile);
 | |
|       }
 | |
|     },
 | |
|     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];
 | |
|         });
 | |
|       }
 | |
|     },
 | |
|     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 => {
 | |
|           this.onSuccess(res, rawFile);
 | |
|           delete this.reqs[uid];
 | |
|         },
 | |
|         onError: err => {
 | |
|           this.onError(err, rawFile);
 | |
|           delete this.reqs[uid];
 | |
|         }
 | |
|       };
 | |
|       const req = this.httpRequest(options);
 | |
|       this.reqs[uid] = req;
 | |
|       if (req && req.then) {
 | |
|         req.then(options.onSuccess, options.onError);
 | |
|       }
 | |
|     },
 | |
|     handleClick() {
 | |
|       if (!this.disabled) {
 | |
|         this.$refs.input.value = null;
 | |
|         this.$refs.input.click();
 | |
|       }
 | |
|     },
 | |
|     handleKeydown(e) {
 | |
|       if (e.target !== e.currentTarget) return;
 | |
|       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 (
 | |
|       <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>
 |