草庐IT

vue+el-upload 上传图片和视频小总结

南柯彡 2023-07-18 原文

一、图片下标,判断,base64,获取img标签等问题

上传图片时用到的accept只会在用户点击上传时添加一个自定义文件类型,如添加了accept=".jpg,.png,",虽然会呈现出符合条件的文件,但用户仍可以通过点击所有文件类型来上传其他类型的文件,此时设置before-upload函数,

参考el-upload上传组件accept属性限制文件类型(案例详解)_辰兮要努力的博客-CSDN博客_el-upload accept 结果只有accept在生效,ElementUI el-upload上传图片限制, before-upload 不生效问题_老电影故事的博客-CSDN博客_beforeupload参考该文章发现自动把自动上传关闭导致这个问题,就只能绑定在on-change里;另外还有:on-exceed 加 limit执行上传限制长度的函数执行。

<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);
        };
      });
    },

 

以及网络图片转base64格式的参考:vue网络图片url转Base64「建议收藏」 - 全栈程序员必看

//初始化时调用    
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);
          });
      };
       
    },

 转换格式的时候,一定要将中间的变量置空!另外为防止根据默认下标有的是网络图片有的不是,导致删除错误,还需要在对象中将该图片现在图片列表中的下标当做添加index属性以当做key值

破解循环中的异步操作,不能直接用for循环,在我看来有效的办法方法体内的num++,再回调此函数

以及在商品详情中仍需要借此转换成base64的格式,但需要先用正则表达式将所有img标签里的src获取到,其他的基本大同小异了。

//正则匹配详情里所有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})
         } 
      })

二、formdata的方式上传视频,原生axios上传,进度条等问题

视频(也是文件)用formdata的方式上传报错,参考:vue上传文件formData入参为空,接口请求500_静静心中的梦_66的博客-CSDN博客用到了原生axios上传,另外在接口中上传和返回时间过长,需要添加一个进度条展示,参考:element ui 图片自定义上传进度条消失问题_我是顾昀峰的博客-CSDN博客_vue和elementui视频上传成功后进度条消失但展示中只会有上传进度的展示,返回以及添加至页面还需要等待很久,进度条以及到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;
        })
      }
     
    },

有关vue+el-upload 上传图片和视频小总结的更多相关文章

  1. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  2. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  3. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  4. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  5. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  6. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  7. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  8. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  9. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  10. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

随机推荐