封装组件el-upload通过v-model (二): 上传多张图片

v-model 上传多张图片 主要是在 重新刷新图片列表 

Vue 效果

 

 

 

file-list 获取图片列表   注意:标红线的地方是重点 其他和单张上传没区别

<template>  
<div>
  <el-upload
  :action="fileUrl"
  :accept="accept"
  list-type="picture-card"
  :on-preview="handlePictureCardPreview"
  :on-remove="handleRemove"
  :on-success="handlePassportSuccess"
  :limit="limit"
  :on-exceed="errortip"
  :file-list="imgeData"
  :before-upload="beforePassportUpload"
  >
  <i class="el-icon-plus"></i>
    <slot name="tip" slot="tip"></slot>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
  <img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>

<script>
import {Url,CCONFIG} from "@/api/apiconfig";
import {getFileUrl} from "@/api/upload";
export default {
  model:{
    prop:"value",
  },
 props: {
     //配合v-model 加载初始值
     value: {
        type: String,
        default: ""
       },

   //大于多少兆开始压缩
       sizeKB:{
        type:Number,
        default: 100
       },
       //最大多少兆
       maxSizeM:{
        type:Number,
        default: 5
       },
       //图片同比压缩比列
       scale:{
        type:Number,
        default: 0.3
       },

     //上传文件类型
      accept:{
        type: String,
        default: "image/jpeg,image/png"
      },
      //上传个数现在
      limit:{
          type: Number,
          default:3
       },
       msg:{
        type: String,
        default: ""
      },


    },
  data() {
    return {
      fileUrl:Url.imge_Upload,
      imageUrl: "",
      dialogImageUrl: '',
      dialogVisible: false,
      imgeData:[],//图片列表
      imgeIdData:[],//返回图片Id列表
    };
  },
  created: function () {
    this.loadImg(this.value)
    },

    //监听父组件值是否在变化
    watch: {
      //有些页面初始初始src没有赋值
      value(newValue, oldValue) {
      this.loadImg(newValue)
      },
    },
    mounted() {},
    methods: {
  
 loadImg(value){
  //获取图片列表
        var arr = value.split(";");
        var data = [];
        for (let i = 0; i < arr.length; i++) {
          if (arr[i])
            data.push({
              imgeId: arr[i],
              url: getFileUrl(arr[i]),
            })
        }
        this.imgeData = data;
 },

//删除回调
      handleRemove(file, fileList) {
           this.imgeData=fileList;//更新图片列

this.returnimgs();
      },
      //点击回调
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
        //上传成功返回值
      handlePassportSuccess(res, file) {
        if (res.code == "0000") {
           var  data={
             uid:file.uid,
             imgeId:res.data.id,
             url:getFileUrl(res.data.id)
               }
            this.imgeData.push(data);//上传成功需要更新图片列表
           this.returnimgs()
       
        };
      },
      //上传多少张
     errortip(){
      var  message="";
      if(this.msg==""){
             message=`最多上传${this.limit}张图片`
      }
       this.$message({message:message,type:'error',offset:10 });
     },
     
     returnimgs(){
       this.imgeIdData=[];
       for (var i = 0; i < this.imgeData.length; i++) {
            this.imgeIdData.push(this.imgeData[i].imgeId)
        }
        this.$emit('input', this.imgeIdData.join(';')) 
        
      },
      //压缩图片 下面的代码都是压缩文件大小 
       beforePassportUpload(file) {
      return new Promise((resolve, reject) => {
        const isJPG = file.type === "image/jpeg";
        const isPNG = file.type === "image/png";
        const  kb= file.size/ 1024;
        const sizeM= file.size/ 1024/1024;
        const isLtKB = kb  < this.sizeKB;
        let bool = false;
        let msg = "";
        
        if ((isJPG || isPNG)&&sizeM<=this.maxSizeM) {//判断是否符合格式要求
          bool = true;
        } 
        else 
        if(sizeM>this.maxSizeM){
           var mag="上传文件必须是小于"+this.maxSizeM+"M";
            this.$message({message:mag,type:'error',offset:10 });
           return reject(file);
        } else 
        {
          this.$message({message:"上传文件必须是jpg、png格式!",type:'error',offset:10 });
          return   reject(file);
        }
        if (bool && !isLtKB) {//如果格式符合要求,但是size过大,对图片进行处理
          let image = new Image(),
          resultBlob = "";
          image.src = URL.createObjectURL(file);
          image.onload = () => {
            
            resultBlob = this.compressUpload(image);//Blob
            resolve(resultBlob);

          };
        } else if (bool && isLtKB) {
           resolve(file);//file
        }
      });
      
    },

    compressUpload(image) {
      let canvas = document.createElement("canvas");//创建画布元素
      let ctx = canvas.getContext("2d");
      let initSize = image.src.length;
      let { width } = image,
          { height } = image;
      canvas.width = width;
      canvas.height = height;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(image, 0, 0, width, height);
      let compressData = canvas.toDataURL("image/jpeg", this.scale); //等比压缩
      let blobImg = this.dataURItoBlob(compressData);//base64转Blob
      return blobImg;
    },
    dataURItoBlob(data) {
      let byteString;
      if (data.split(",")[0].indexOf("base64") >= 0) {
        byteString = atob(data.split(",")[1]);//转二进制
      } else {
        byteString = unescape(data.split(",")[1]);
      }
      let mimeString = data
        .split(",")[0]
        .split(":")[1]
        .split(";")[0];
      let ia = new Uint8Array(byteString.length);
      for (let i = 0; i < byteString.length; i += 1) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new Blob([ia], { type: mimeString });
    },
   },
};
</script>
posted @ 2020-05-18 11:14  筑基期  阅读(2574)  评论(0编辑  收藏  举报