最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • vuejs| 通过promise实现图片批量上传

    正文概述 掘金(sanhuamao)   2020-12-01   580

    需求

    • 批量上传头像,且头像能上传到对应的人员信息上
    • 上传限制
    • 不是立刻上传

    修改默认样式

    因为觉得element组件的el-upload有点复杂,所以这里使用原始的input标签。不过通常需要换掉原始样式,只需给input添加一条style="display:none",接着用具有其他样式的元素包裹它,并在该元素上添加事件(不包裹也行,包裹主要是为了容易看)。

    <el-button  @click="beforeImagesUpload">批量上传图片
        <input type="file" style="display:none" id="file" multiple>
    </el-button>
    

    点击触发该事件相当于点击了里面的input元素

    beforeImagesUpload(){
        let file = document.querySelector('#file')//获取最原始的input元素
        file.click()//触发
    }
    

    保存图片信息

    现在要在上面的beforeImagesUpload进行丰富。由于我希望头像能上传到对应的人员信息上,那么我至少需要有一个标识帮助我识别这个头像属于谁。所以上传前先要求用户将图片命名为对应的id,接着前端通过图片名称来获取对应的标识进行文件上传

    这里先了解一下图片文件的数据格式:

    vuejs| 通过promise实现图片批量上传

    如果不想立刻上传,那么很容易想到的办法就是先将文件储存起来:

    fileList:[]
    
    async beforeImagesUpload(){
        let fileList=[]
        let file = document.querySelector('#file')
        file.click()
        file.onchange = function (event) {
          let files = event.target.files
          for(let i=0;i<files.length;i++){
                let file=files[i]
                let filename=file.name//获取图片名称(有后缀)
                let id=filename.slice(0,filename.indexOf('.'))//获取图片名称(无后缀)
                fileList.push({file:file,id:id,filename:filename})//整合成新的图片对象,并将其加进图片列表中
            }
    	}
        console.log(fileList)//出错
    }
    

    然而,你会发现控制台打印数据是空的。这是由于同步致使函数直接跳过处理图片的部分,马上到了后面的console.log(fileList)

    Promise实现异步

    这时可以使用promise对象解决。promise对象的函数内有两个参数:resolve和reject,它们是两个回调函数,前者表示成功时的回调,后者表示失败时的回调,这里先不考虑reject的情况:

    async beforeImagesUpload(){
      let that=this//改变作用域
      let promise= new Promise(function (resolve, reject) {
          let fileList=[]
          let file = document.querySelector('#file')
          file.click()
          file.onchange = function (event) {
            let files = event.target.files
          	for(let i=0;i<files.length;i++){
                let file=files[i]
                let filename=file.name
                let id=filename.slice(0,filename.indexOf('.'))
                fileList.push({file:file,id:id,filename:filename})
            }
            resolve(fileList)//通过resolve将fileList抛出,在后续使用
        }
      })
      
      //接着就是处理抛出来的数据了:
      //promise接受两个回调函数作为参数:一个状态变为Resolved时调用,一个是状态变为Reject时调用。
      //这两个函数都接受Promise对象传出的值作为参数。
      //第二个函数是可选的,这里先不考虑第二个函数。
      promise.then(function(value) {
        //状态为resolved时调用,这里的value就是resolve抛出的数据
        console.log(value)//成功打印
        that.fileList=value//储存
      });
      
    },
    

    为了更好的处理数据,建议把value传给另一个函数处理:

    promise.then(function(value) {
        	that.upload(value)//正式上传 后面写
    	}
    )
    

    添加限制

    假设上传图片有两个前提:

    1.最多只能上传10张

    2.图片大小不能大于300k

    这里reject就派上用场的了。现在修改一下promise对象中的内容:

    //...
    let promise= new Promise(function (resolve, reject) {
        //...
        file.onchange = function (event) {
          let files = event.target.files
          
          //1.判断图片数量
          if(files.length>10){
            reject('page')//如果多于10张,判定为失败,抛出错误'page',停止向下运行。
          }else{
            for(let i=0;i<files.length;i++){
              let file=files[i]
              
              //2.判断图片大小
              const is300K=file.size>300*1024//判定指标,是否大于300k
              if (is300K) {
                reject('size')//如果大于300k,判定为失败,抛出错误'size',停止向下运行。
              }
              
              let fileName=file.name
              let phone=fileName.slice(0,fileName.indexOf('.'))
              fileList.push({file:file,phone:phone,fileName:fileName})
            }
          }
          resolve(fileList)//上面均没有出错时抛出
      }
    })
    

    接下来就是处理回调函数:

    async beforeImagesUpload(){
      //...
      let promise= new Promise(function (resolve, reject) {
          //...
      })
      
      
      //这里需要promise的第二个回调函数,在状态为Reject时调用:
      promise.then(function(value) {
        that.upload(value)//正式上传
      }, function(error) {
        //上面设置了两种错误,这里可以用if来判断错误类型,并给出对应的响应
        if(error=='page'){
          that.$message.error('最多只能上传10张照片!')
        }else if(error=='size'){
          that.$message.error('上传的图片大小不能超过300K!');
        }
      });
        
      
    },
    

    图片上传

    不是立刻上传,需要将upload(value)传过来的值先保存起来,如this.fileList=value,再经过中间函数处理,配合弹框使用。

    为了简便,这里就直接上传了。批量上传,说白了其实就是一个一个地上传,这里我使用的是axios插件

    upload(value){
      value.map(item=>{
        let fd = new FormData()
        fd.append('image',item.file)
        fd.append('id',item.id)
        axios.post("url",fd,{headers:{'Content-Type': 'multipart/form-data'}})
      })
    },
    

    下载网 » vuejs| 通过promise实现图片批量上传

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元