iview Upload组件的坑

本文详细解析了iviewUpload组件中实现上传进度条的过程,包括如何通过监听上传事件来更新进度百分比,以及如何在界面上正确显示进度条。针对官方文档描述模糊的问题,文章提供了具体的代码示例和解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

iview Upload 上传显示进度条的坑

直接先来官方代码

上官方文档 demo 代码

<template>
  <div class="demo-upload-list" v-for="item in uploadList">
    <template v-if="item.status === 'finished'">
      <img :src="item.url">
      <div class="demo-upload-list-cover">
        <Icon type="ios-eye-outline" @click.native="handleView(item.name)"></Icon>
        <Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
      </div>
    </template>
    <template v-else>
      <Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
    </template>
  </div>
  <Upload ref="upload" :show-upload-list="false" :default-file-list="defaultList" :on-success="handleSuccess" :format="['jpg','jpeg','png']" :max-size="2048" :on-format-error="handleFormatError" :on-exceeded-size="handleMaxSize" :before-upload="handleBeforeUpload" multiple type="drag" action="//jsonplaceholder.typicode.com/posts/" style="display: inline-block;width:58px;">
    <div style="width: 58px;height:58px;line-height: 58px;">
      <Icon type="ios-camera" size="20"></Icon>
    </div>
  </Upload>
  <Modal title="View Image" v-model="visible">
    <img :src="'https://o5wwk8baw.qnssl.com/' + imgName + '/large'" v-if="visible" style="width: 100%">
  </Modal>
</template>
<script>
export default {
  data () {
    return {
      defaultList: [
        {
          'name': 'a42bdcc1178e62b4694c830f028db5c0',
          'url': 'https://o5wwk8baw.qnssl.com/a42bdcc1178e62b4694c830f028db5c0/avatar'
        },
        {
          'name': 'bc7521e033abdd1e92222d733590f104',
          'url': 'https://o5wwk8baw.qnssl.com/bc7521e033abdd1e92222d733590f104/avatar'
        }
      ],
      imgName: '',
      visible: false,
      uploadList: []
    }
  },
  methods: {
    handleView (name) {
      this.imgName = name;
      this.visible = true;
    },
    handleRemove (file) {
      const fileList = this.$refs.upload.fileList;
      this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);
    },
    handleSuccess (res, file) {
      file.url = 'https://o5wwk8baw.qnssl.com/7eb99afb9d5f317c912f08b5212fd69a/avatar';
      file.name = '7eb99afb9d5f317c912f08b5212fd69a';
    },
    handleFormatError (file) {
      this.$Notice.warning({
        title: 'The file format is incorrect',
        desc: 'File format of ' + file.name + ' is incorrect, please select jpg or png.'
      });
    },
    handleMaxSize (file) {
      this.$Notice.warning({
        title: 'Exceeding file size limit',
        desc: 'File  ' + file.name + ' is too large, no more than 2M.'
      });
    },
    handleBeforeUpload () {
      const check = this.uploadList.length < 5;
      if (!check) {
        this.$Notice.warning({
          title: 'Up to five pictures can be uploaded.'
        });
      }
      return check;
    }
  },
  mounted () {
    this.uploadList = this.$refs.upload.fileList;
  }
}
</script>
<style>
.demo-upload-list {
  display: inline-block;
  width: 60px;
  height: 60px;
  text-align: center;
  line-height: 60px;
  border: 1px solid transparent;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
  position: relative;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  margin-right: 4px;
}
.demo-upload-list img {
  width: 100%;
  height: 100%;
}
.demo-upload-list-cover {
  display: none;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.6);
}
.demo-upload-list:hover .demo-upload-list-cover {
  display: block;
}
.demo-upload-list-cover i {
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  margin: 0 2px;
}
</style>

  1. 按照官方文档,搬下来代码,执行,最后的结果就是。。。进度条 ?? 不存在的,而且官方文档写的灰常灰常模糊,获取进度的百分比虽然在 filelist 中有 一个percent 的参数,但是,然并卵 需要调用内部的函数实现:以下是实现在控制台打印出进度百分比

    handleProgress (event, file, fileList) {
    event.target.onprogress = (event)=>{ 
           // event.loaded		已经上传了文件大小
           // event.total		上传文件总大小
           let uploadPercent = ((event.loaded / event.total) * 100).toFixed(1) + '%'
           console.log(uploadPercent) 		
       }
    }
    
  2. 作为一个好学的好孩子(不要吐槽我)怎么能就此打住呢,我要的效果是,和官方展示的效果一样的东西,不要只是在控制台输出一个百分比

    坑爹 的文档,没有这段代码不说,也偷懒

    • 继续研究打印出来的属性 percentage showProgress 既然有这两个属性那么,说明他们就可以做一些手脚;

    • 继续往下翻,咦看到了他们的 setter getter 方法,我去,我震惊了,尼玛,你有方法你就写清楚啊,不明不白的,你 搞鸡儿 啊 还好我有 锲而不舍 的精神(纯属自吹,不要拿刀砍我),其实是强迫症患者的我;

    • 接下来我就给他动 手术 了(因为我展示的是一张图片,所以动 手术 的时候,也方便些,嘿嘿)

    • 上代码:在原文档代码中,把下边这段代码放到 methods 中,然后在 <Upload> 中加入上传中的钩子 :on-progress="handleProgress" 即可:

      handleProgress (event, file, fileList) {
        console.log('上传中', event); // 继承了原生函数的 event 事件
        console.log('上传中 file', file); // 上传的文件
        console.log('上传中 fileList', fileList); // 上传文件列表包含file
            
        // uploadList 就是 原文档中的那个渲染的 uplist 是个数组,所以要把filelist 赋值给他
        this.uploadList = fileList
      	 
        // 调用监听 上传进度 的事件
        event.target.onprogress = (event) => {
          let uploadPercent = parseFloat(((event.loaded / event.total) * 100).toFixed(2))	// 保留两位小数,具体根据自己需求做更改
      
          // 手动设置显示上传进度条 以及上传百分比
          file.showProgress = true
          file.percentage = uploadPercent
        }
      }
      
  3. 至此就实现了官方文档中实例的样子(自定义上传图片), 有不对的地方,欢迎小伙伴们吐槽;

### iview Upload 组件常见问题及其解决方案 #### 多文件上传并限制数量 对于多文件上传的需求,iview 的 `upload` 组件默认提供了开启多选的功能,即设置 `multiple=true` 属性。然而,该组件并未内置对上传文件数目的限制功能。一种有效的解决办法是对原生事件监听器进行扩展,从而实现自定义逻辑。 ```javascript methods: { beforeUpload(file) { const check = this.fileList.length < 3; if (!check) { this.$Notice.warning({ title: '最多只能上传3张图片' }); } return check; }, } ``` 上述代码展示了如何利用钩子函数 `before-upload` 来阻止超出设定上限的文件被加入队列[^1]。 #### 数据传输至Node.js失败 当尝试向 Node.js 后端发送额外数据时遇到困难,可能是因为请求体格式不匹配服务器预期所致。确保客户端正确设置了表单字段名称,并且服务端能够解析 multipart/form-data 类型的数据包非常重要。 ```javascript // 客户端配置项 <template> <iView.Upload :data="extraData"> </template> <script> export default { data() { return { extraData: { key: "value" }, // 自定义参数对象 }; }, }; </script> ``` 同时确认 Express 或 Koa 等中间件已安装 body-parser 和 multer 插件用于处理 POST 请求中的 JSON 及文件流[^2]。 #### 进度条更新异常 有时开发者会注意到进度条反馈机制存在问题,比如百分比计算错误或是根本没有任何变化。这是因为浏览器自带的 XHR 对象并不总是能可靠地报告上传状态的变化。可以通过重写 onprogress 方法来获取更精确的状态信息: ```javascript handleProgress(event, file, fileList){ event.target.onprogress = function(e){ var percentCompleted = Math.round((e.loaded * 100)/ e.total); console.log('当前完成度:',percentCompleted+'%'); }.bind(this); }, ``` 这段脚本直接操作底层网络事件处理器,使得即使在网络条件不佳的情况下也能获得较为真实的进度指示[^3]。 #### 文件转换为Base64编码 针对特定应用场景下的特殊需求——如需将本地选取的照片即时展示给用户查看,则可通过 canvas API 实现图像预览效果的同时将其转化为 base64 字符串形式存储或传递。 ```javascript function getBase64Image(imgUrl,callback){ let image=new Image(); image.setAttribute("crossOrigin",'Anonymous'); image.onload=function(){ let canvas=document.createElement("canvas"); canvas.width=image.width; canvas.height=image.height; let context=canvas.getContext("2d"); context.drawImage(image,0,0); callback(canvas.toDataURL("image/png")); }; image.src=imgUrl; } getBase64Image('/path/to/image',function(base64Img){ document.getElementById('preview').src=base64Img; }); ``` 此段 JavaScript 函数接受一个 URL 参数作为输入,加载完成后执行回调并将结果赋值给指定 DOM 元素 src 属性显示出来[^4]。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值