SOURCE

console 命令行工具 X clear

                    
>
console
var UploadImg = Vue.component('UploadImg',{
  name: "UploadImg",
  props: ["index", "imgItem"],
  template:`<div class="img-box">
    <div class="img" :style="{backgroundImage: 'url('+ img +')'}" @click.self='choose'>
      <mu-circular-progress v-show='radio>0 && radio<100' class="img-progress" mode="determinate" :size="22" color="#fff" :strokeWidth="1" :value="radio" />
      <div class="fail" v-show="uploadFail" @click='uploadImg'>
        <img src="../../assets/images/img-common/failImg.png" alt="">
      </div>
      <transition name='fade' mode='in-out'>
        <div v-show="radio>0 && radio<100 " class="black"></div>
      </transition>
      <i class='del' v-show="img&&hasImg" @click="delImg"></i>
    </div>
    <input v-show='false' ref='file' type="file" accept="image/*" @change="getImg($event)">
  </div>`
  data() {
    return {
      radio: 0,
      img: "./static/images/img-common/addImg.png",
      hasImg: false,
      imgData: "",
      radio: 0,
      file: "",
      uploadFail: false
    };
  },
  computed: {
    ...mapState(["userCode", "comCode", "channel", "sessionId"])
  },
  methods: {
    choose() {
      if (this.imgItem) {
        this.$refs.file.click();
      } else {
        // 如果为空,触发父组件的文件选择
        this.$emit("choose");
      }
    },
    /**
     * 获取input表单文件
     * @param {Object} 当前表单对象
     */
    getImg(e) {
      let self = this;
      if (!e.target.value) {
        return;
      }
      this.compressImg(e.target.files[0]);
      this.$refs.file.value = null;
    },
    /**
     * 压缩图片处理
     * @param {string} file
     */
    compressImg(file) {
      let self = this;
      this.img = URL.createObjectURL(file);
      this.imgType = file.name
        .toLowerCase()
        .split(".")
        .splice(-1)[0]; //获取图片类型
      this.hasImg = true;
      this.$utils.compressImg(file, 0.8).then(file => {
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function() {
          console.log("reader.result", reader.result.length);
          self.imgData = reader.result.substring(22);
          var equalIndex = reader.result.indexOf("=");
          if (self.imgData.indexOf("=") > 0) {
            self.imgData = self.imgData.substring(0, equalIndex);
          }
          self.radio = 0.1; // 模拟已经在上传图片
          self.uploadImg();
        };
      });
    },
    /**
     * 上传图片
     */
    uploadImg() {
      let self = this;
      this.uploadFail = false;
      let baseData = {
        channel: self.channel,
        comCode: self.comCode,
        userCode: self.userCode,
        imageMsg: [
          {
            fileIO: self.imgData,
            fileType: self.imgType
          }
        ]
      };
      let data = self.$utils.getRequestParam(
        "100000043",
        JSON.stringify(baseData),
        this.sessionId
      );
      self.$axios({
          method: "post",
          url: '/upload',
          data: data,
          onUploadProgress: function(event) {
            if (event.lengthComputable) {
              self.radio = (event.loaded / event.total) * 100;
            }
          }
        })
        .then(function(resp) {
          let data = resp.data.respBizMsg;
          self.$emit("change", {
            index: self.index,
            value: {
              id: self.imgItem.id,
              data: data.imageUrl[0]
            }
          });
          // self.$emit('change',data.imageUrl[0])
        })
        .catch(function(response) {
          alert("图片上传失败");
          self.uploadFail = true;
        });
    },
    delImg() {
      this.$emit("del");
    }
  },
  beforeMount() {
    if (this.imgItem) {
      // 判断是否已有图片
      if (typeof this.imgItem.data === "string") {
        this.img = this.imgItem.data;
        this.hasImg = true;
      } else {
        this.compressImg(this.imgItem.data);
      }
    }
  }
})
var UploadImgList =Vue.component('UploadImgList',{
  name: "UploadImgList",
  template:`<div class='img-list'>
    <UploadImg v-for="(item,index) in fileList" :key='item.id' :index='index' :imgItem='item' @change='getData' @choose='chooseFile' @del='delImg(index)'></UploadImg>
    <input v-show='false' ref='files' type="file" accept="image/*" @change="getImg($event)">
    <UploadImg v-show='fileList.length<length' @choose='chooseFile'></UploadImg>
  </div>`
  model:{
    prop:'itemVal',
    event:'change'
  },
  components: { UploadImg },
  props: ["itemVal","length"],
  data() {
    return {
      fileList: [],
      imgList: [],
      id: 0
    };
  },
  watch:{
    itemVal(){
      if(this.itemVal && this.itemVal.length>0){
        this.id = this.itemVal[this.itemVal.length-1] ? this.itemVal[this.itemVal.length-1].id : 0
        this.imgList = JSON.parse(JSON.stringify(this.itemVal))
        this.fileList = JSON.parse(JSON.stringify(this.itemVal))
      }
    }
  },
  methods: {
    // 子组件触发,传递图片数据
    getData(item) {
      this.imgList[item.index] = item.value;
      this.$emit('change',JSON.parse(JSON.stringify(this.imgList)))
    },
    // 删除指定图片
    delImg(index) {
      this.fileList.splice(index, 1);
      this.imgList.splice(index, 1);
      this.$emit('change',this.imgList)
    },
    chooseFile() {
      this.$refs.files.click();
    },
    /**
     * 获取input 图片
     * @param {Object} 对象
     */
    getImg(e) {
      let self = this;
      if (!e.target.value) {
        return;
      }
      let arr = Array.prototype.slice.call(e.target.files);
      if (arr.length > 1) {
        arr.forEach((item, index) => {
          this.id++;
          this.fileList.push({ id: this.id, data: item });
        });
      } else {
        this.id++;
        this.fileList.push({ id: this.id, data: arr[0] });
      }
      this.$refs.files.value = null;
    }
  },
  beforeMount(){
    if(this.itemVal && this.itemVal.length>0){
      this.id = this.itemVal[this.itemVal.length-1].id ? 	this.itemVal[this.itemVal.length-1].id : 0
      this.imgList = JSON.parse(JSON.stringify(this.itemVal))
      this.fileList = JSON.parse(JSON.stringify(this.itemVal))
    }
  }
})
var app = new Vue({
    el: '#app',
  data:{}
});
<div id="app">
  <UploadImgList/>
</div>
.img-list {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  flex-wrap: wrap;
}
.img-box {
  position: relative;
  width: 1.946667rem;
  height: 1.946667rem;
  margin-right: 0.26667rem;
  margin-top: 0.26667rem;
  background: #f0f0f0;
  .img {
    position: absolute;
    background: center no-repeat;
    z-index: 10;
    width: 100%;
    height: 100%;
    background-size: cover;
  }
  .img-progress {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 100;
    background: url(../../assets/images/img-common/huan.png) no-repeat;
    background-size: 100% 100%;
  }
  .black {
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    position: absolute;
    top: 0;
    left: 0;
    z-index: 20;
  }
  .del {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(80%, -80%);
    background: url(../../assets/images/img-common/delete.png) no-repeat;
    background-size: contain;
    width: 0.373333rem;
    height: 0.373333rem;
    margin: 0.2rem;
    z-index: 1001;
  }
  .fail {
    position: absolute;
    background: rgba(0, 0, 0, 0.5);
    background-size: 100% 100%;
    width: 100%;
    height: 100%;
    z-index: 110;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
    img {
      width: 0.586667rem;
      height: 0.586667rem;
    }
  }
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}