vue+el-upload upload pictures and videos summary

1. Image subscript, judgment, base64, obtaining img tags and other issues

The accept used when uploading pictures will only add a custom file type when the user clicks to upload, such as adding accept=".jpg,.png,", although the qualified files will be displayed, the user can still click All file types to upload other types of files, set the before-upload function at this time,

Refer to the accept  attribute of the el-upload upload component to limit the file type (case details ) _Old movie story blog-CSDN blog_beforeupload Refer to this article and find that automatically turning off automatic uploading causes this problem, so it can only be bound in on-change; in addition: on-exceed plus limit executes the function of uploading limit length implement.

<el-form-item label="商品轮播图设置" label-width="160px">
          <p>商品轮播图</p>
          <p class="tips">
            仅支持上传图片,最少上传一张 最多可上传十张, 已上传
            <span>{
   
   { canonicalImage.length }}</span>
            / 10
          </p>
          <div class="form_canonicalImage">
            <el-upload
              action="#"
              list-type="picture-card"
              :auto-upload="false"
              :limit="10"
              :multiple="true"
              :file-list="canonicalImage"
              :on-change="uploadChange"
              :on-remove="handleRemove"
              :on-exceed="handleExceed"
              :on-preview="handlePreview"
              :before-remove="beforeRemove"
              :before-upload="beforeImageUpload" 
              ref="mYupload"             
              accept=".jpg,.png,"
            >
              <i slot="default" class="el-icon-plus"></i>
            </el-upload>
            <el-dialog :visible.sync="dialogVisible">
              <img width="100%" :src="dialogImageUrl" alt="" />
            </el-dialog>
          </div>
        </el-form-item>

methods

    //删除之前的钩子
    beforeRemove(file, fileList) {
      return this.$confirm('删除该图片, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })               
    },
    // 删除轮播图
    handleRemove(file, fileList) {
      this.canonicalImage = JSON.parse(JSON.stringify(fileList));
    },
    //触发上传限制
    handleExceed() {
      this.$message.warning("上传超出限制!");
    },
    //预览
    handlePreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 添加轮播图
    uploadChange(file, fileList) {
        //截取出文件末尾的类型       
      let fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
      const whiteList = ["jpg", "png"];
      const isLt2M = file.size / 1024 / 1024 < 4;
      if (whiteList.indexOf(fileSuffix) === -1) {
        this.$message.error("上传文件只能是jpg/png格式");
        
        fileList.pop();
        return false;
      }     
      else if (!isLt2M) {
        this.$message.error("上传文件大小不能超过 4MB");
        fileList.pop();
        return false;
      }else{
       
      this.uploadImage_loading = true;
      this.getBase64(file.raw).then((res) => {
        productcopyAPI
          .savefile({
            imagesBase64: res,
            filetype: "image",
            fileName: file.name,
            keyName: "keyName",
            ticket: this.ticket,
          })
          .then(({ data }) => {
            fileList.forEach((item) => {
              item.uid == file.uid && (item.url = data.data[0].url);
            });
            this.canonicalImage = JSON.parse(JSON.stringify(fileList));
          })
          .catch((error) => {
            this.uploadImage_loading = false;
            this.$message.error(error);
          });
      });
      }
    },

    // 图片转base64
    getBase64(file) {
      return new Promise(function (resolve, reject) {
        let reader = new FileReader();
        let imgResult = "";
        reader.readAsDataURL(file);
        reader.onload = function () {
          imgResult = reader.result;
        };
        reader.onerror = function (error) {
          reject(error);
        };
        reader.onloadend = function () {
          resolve(imgResult);
        };
      });
    },

 

And a reference for converting network pictures to base64 format: vue network picture url to Base64 "recommended collection" - a must-see for full-stack programmers

//初始化时调用    
getimage() {
      this.$refs.mYupload.clearFiles();
      this.uploadImage_loading = true;
      let data = [];
      
      this.canonicalImage.forEach((item, i) => {
        if (item.url.includes("baidu")) {
          data.push({ url: item.url, index: i });         
        }else{
          data = []
        }
      });
      let num = 0;
      if(data[num]){
        this.imageUrlToBase64(data, num);
      }      
    },
    //网络图片url转换为base64
    imageUrlToBase64(data_, num) {
      //一定要置空!!!!
      this.base64Datas = [];
      let image = new Image();
      //解决跨域问题
      image.setAttribute("crossOrigin", "anonymous");
      
      let imageUrl = data_[num].url;    
      image.src = imageUrl;
      let that = this;
      //image.onload为异步加载
      image.onload = () => {
        var canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;
        var context = canvas.getContext("2d");
        context.drawImage(image, 0, 0, image.width, image.height);
        var quality = 0.8;
        //这里的dataurl就是base64类型
        var dataURL = canvas.toDataURL("image/jpeg", quality); //使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
        //数组存放图片base64
        this.base64Datas = dataURL;
        productcopyAPI
          .savefile({
            imagesBase64: this.base64Datas,
            filetype: "image",
            fileName: "file.name",
            keyName: "keyName",
            ticket: this.ticket,
          })
          .then(({ data }) => {
            data_[num].url = data.data[0].url;
            if(num <data_.length-1){
                num++               
                this.imageUrlToBase64(data_, num);
             }else{
              data_.forEach((item,i)=> {
                
                this.canonicalImage[item.index].url = item.url;
              });
             }

            this.uploadImage_loading = false;
          })
          .catch((error) => {
            
            this.uploadImage_loading = false;
            this.$message.error(error);
          });
      };
       
    },

 When converting the format, be sure to empty the intermediate variables! In addition, in order to prevent deletion errors due to the default subscripts of network pictures and others, it is also necessary to add the index attribute to the object as the key value of the subscript in the picture list.

To crack the asynchronous operation in the loop, you cannot use the for loop directly. In my opinion, the effective way is to use num++ in the method body, and then call back this function

And in the product details, it still needs to be converted into base64 format, but you need to use regular expressions to get all the src in the img tag first, and the rest are basically the same.

//正则匹配详情里所有img标签    
      var regex0 = new RegExp(/(?<=(img src="))[^"]*?(?=")/gims); //eslint-disable-line
      this.detailimgtag = this.outdetail.match(regex0);
      let data= []
        let num = 0
      this.detailimgtag.forEach((item,i)=>{
         if (item.includes("baidu")) {
          data.push({url:item,index:i})
         } 
      })

2. Upload video by formdata, native axios upload, progress bar and other issues

The video (also a file) is uploaded in formdata and reports an error. Refer to: vue uploads a file formData input parameter is empty, and the interface requests 500 And the return time is too long, you need to add a progress bar display, refer to: element ui image custom upload progress bar disappears_I am Gu Yunfeng's blog-CSDN blog_After the vue and elementui video upload is successful, the progress bar disappears but is displayed There will only be a display of the upload progress, and it will take a long time to return and add to the page, and the progress bar has reached 100%.

// 视频上传函数
    uploadVideo(file,fileList) {
      //截取出文件末尾的类型
      let fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
      const blackList = ["mp4"];
      const isLt2M = file.size / 1024 / 1024 < 10;
      if (blackList.indexOf(fileSuffix) === -1) {
        this.$message.error("上传文件只能是mp4格式");
        
        // this.canonicalVideo = fileList.slice(0,1) 
        
        return false;
      }else if (!isLt2M) {
        this.$message.error("上传文件大小不能超过 10MB");
        // this.canonicalVideo = fileList.slice(0,1)
        return false;
      }else {
      this.isShowUploadVideo = false;
    this.videoFlag = true;
      var formdata = new FormData();
      formdata.append("file", file.raw);
      formdata.append("filetype", "video");
      formdata.append("ticket", this.ticket);
      formdata.append("keyname", "keyName");
      formdata.append("filenames", file.name);
      this.$axios.post('https://aicaigoufuwuapi.yiwangtui.com/api/upload/UploadFile',formdata,{
        onUploadProgress: progressEvent => {
          if(progressEvent.lengthComputable)
            var val = parseInt(progressEvent.loaded / progressEvent.total * 100 ).toFixed(0)
            this.videoUploadPercent = Math.floor(val)-1;
          }
          }
          )    
      .then(res=>{
          this.canonicalVideo=[{
            src:res.data.data.data[0].url,
            video_id:''
            }];
            this.videoFlag = false;
            this.videoUploadPercent  = 100;
        })
        .catch((error)=>{
          this.$message.error(error+',请重新上传!');         
          this.videoFlag = false;
          this.videoUploadPercent = 0;
        })
      }
     
    },

Guess you like

Origin blog.csdn.net/weixin_42574985/article/details/127763439