vue多图上传封装

在原生js的基础上进行的封装,多图和单图的关键在于input的multiple属性

<template>
  <div class="upload-wrap">
    <input :id="upfileId" type="file" name="fileName" :multiple="multiple" :accept="accept" />
    <img v-if="imageUrl" :src="imageUrl" class="avatar" />
    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    <span v-if="imageUrl" class="el-upload__tip">{{uploadTip}}</span>
  </div>
</template>
<script>
import api from "api";
export default {
  name: "com-upload",
  props: {
    upfileId: { // 组件id
      type: String,
      default: "upload"
    },
    multiple: { // false默认单图上传,true多图上传
      type: Boolean,
      default: false
    },
    accept: { // 接收文件的类型
      type: String,
      default: "image/*"
    },
    size: { // 文件大小限制
      type: String,
      default: "3M"
    },
    uploadTip: { //上传文件类型文本提示
      type: String,
      default: "jpg/jpeg/gif/png"
    },
    type: { //来源
      type: String,
      default: "logo"
    },
    fileType: {
      type: String,
      default: ""
    },
    imageUrl: { //默认样式图片
      type: String,
      default: "logo"
    },
    cb: { // 上传回调
      type: Function,
      default: function() {}
    }
  },
  data() {
    return {
      uploading: false,
      formValidations: true
    };
  },
  computed: {
    fileSize() {
      let tempSize = "";
      let mt = this.size.match(/^([\d\.]+)([^\d\.]*)$/i);
      if (!!mt) {
        let bit = mt[2].toLowerCase();
        if (bit === "m" || bit === "mb") {
          tempSize = mt[1] * 1024 * 1024;
        } else if (bit === "kb" || bit === "k" || bit === "KB") {
          tempSize = mt[1] * 1024;
        }
      }
      return tempSize;
    }
  },
  mounted() {
    this.initUpload();
  },
  methods: {
    initUpload() {
      let _this = this;

      $("#" + _this.upfileId)
        .unbind("change")
        .bind("change", function() {
          var $this = $(this);
          var This = this;
          var len = This.files.length;
          _this.formValidations = true;
          _this.uploading = false;

          if (!!_this.numMax && len > _this.numMax) {
            _this.$message.error("单次上传不能超过" + _this.numMax + "个文件!");
            $this.val("");
            return false;
          }
          for (var i = 0; i < len; i++) {
            if (!!_this.size && This.files.item(i).size > _this.fileSize) {
              _this.formValidations = false;
              _this.$message.error("文件大小不能超过" + _this.size + "");
              $this.val("");
              return false;
            }
            //判断文件类型是否合格
            if (
              !!_this.fileType &&
              !eval(_this.fileType).test(This.files.item(i).name)
            ) {
              _this.formValidations = false;
              _this.$message.error("文件类型不正确!");
              $this.val("");
              return false;
            }
          }

          if (_this.uploading || !_this.formValidations) {
            _this.formValidations = true;
            return false;
          }
          let formData = new FormData($this.parents(".form_upload")[0]);
          _this.uploading = true;
          api.request("uploadFiles", formData, result => { // 存储图片的接口
            if (result.status == 0) {
              let obj = {};
              let morefile = [];

              for (let j = 0; j < result.data.length; j++) {
                morefile.push(result.data[j].file);
              }

              obj[_this.type] = morefile;
              obj["upfileId"] = _this.upfileId;
              
              !!_this.cb && _this.cb(obj);
            } else {
              _this.$message.error("图片上传失败!");
            }
            $this.val("");
            _this.uploading = false;
          });
        });
    }
  }
};
</script>
<style scoped>
.upload-wrap {
  width: 122px;
  height: 122px;
  position: relative;
  border: 1px dotted #dfe5ec;
  border-radius: 5px;
}
.upload-wrap input {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  filter: alpha(opacity=0); /* 兼容IE */
  z-index: 9;
}
.upload-wrap .avatar-uploader-icon {
  position: absolute;
  top: 0px;
  left: 0px;
  font-size: 28px;
  color: #8c939d;
  width: 120px;
  height: 120px;
  line-height: 120px;
  text-align: center;
  z-index: 1;
}
.upload-wrap .avatar {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 120px;
  height: 120px;
  display: block;
  z-index: 1;
  border-radius: 5px;
}
.upload-wrap .el-upload__tip {
  position: absolute;
  width: 100%;
  height: 40px;
  left: 0;
  bottom: 0;
  padding: 4px 15px 0;
  background-color: rgba(0, 0, 0, 0.3);
  color: #fff;
  z-index: 1;
  border-bottom-left-radius: 5px;
  border-bottom-right-radius: 5px;
}
</style>

组件的运用

      <form class="form_upload">
        <comupload
          type="logo"
          size="5M"
          :upfileId="'upfileId' + index"
          uploadTip="jpg/jpeg/gif/png <3M"
          imageUrl="../../images/default.png"
          fileType="/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/"
          :multiple="true"
          :cb="uploadCompanyImgs"
        ></comupload>
      </form>

  // 上传图片后获得图片路径的回调方法
  methods: {
    uploadCompanyImgs(data) {
      console.log('data', data)
    }
  }

猜你喜欢

转载自www.cnblogs.com/qlongbg/p/12705258.html