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>
 |