父组件
async handleDownload(e, row) {
     
      e.preventDefault();
      row.downLoading = true;
      let downFile = new file_down();
      const a = document.createElement("a");
      console.log(this.$store.state.app.downList)
      let downList = [...this.$store.state.app.downList];
      let len = downList.length;
      this.$downNotify(); // 初始化下载弹窗
      this.$store.commit("app/SETISSHOWDOWN", true);
      this.objNow = {
        id: len + 1,
        name: ext(row.privateUrl),
        loading: true,
        url:row.privateUrl,
        percentage:0,
        daxiao:100
      };
 let obj=this.objNow
 this.$store.commit("app/SETDOWNLIST", downList);
 let timestamp = Date.parse(new Date());
 await this.getBlob(row.privateUrl,downList.length,downList,row,obj)
 
 
 /**
     * @function {下载}
     */
    getBlob (fileUrl,index,downList,row,obj) {
       let timer=''
      return new Promise(resolve => {
        const xhr = new XMLHttpRequest();
        // xhr.timeout=1000
        xhr.open('GET', fileUrl, true);
        //监听进度事件
        xhr.addEventListener(
          'progress',
          function (evt) {
            if (evt.lengthComputable) {
              let percentComplete = evt.loaded / evt.total;
              // percentage是当前下载进度,可自行处理
              let percentage = percentComplete * 100;
              // if(downList.length-1>=index){
                window.clearInterval(timer)
                obj.percentage=percentage
                obj.size=evt.total
                obj.rowName=row.name
                obj.timeout=''
                obj.timer=120
                if(percentage!=100){
                  timer=window.setInterval((()=>{
                  if(obj.timer>0){
                  downList.forEach((item,i)=>{
                    if(item.rowName==row.name){
                      obj.timer=obj.timer-1
                      downList.splice(i,1,obj)
                    }
                  })
                   
                  }else{
                    xhr.abort()
                    window.clearInterval(timer)
                    downList.forEach((item,i)=>{
                    if(item.rowName==row.name){
                      downList.splice(i,1,obj)
                    }
                  })
                    // downList.splice(index,1,obj)
                  }
                }),1000)
                }
               
                // downList[index]=obj
                downList.splice(index,1,obj)
                // this.$set(downList[index],)
               
              // }
            }
          },
          false
        );
  
 xhr.responseType = 'blob';
        let arr=fileUrl.split('/')
        let names=arr[arr.length-1]
       
        xhr.onload = (res) => {
          if (xhr.status === 200) {
            console.log(xhr.response)
            let blob=new Blob([xhr.response])
            var a=document.createElement('a')
            a.download=names
            a.style.display='none'
            let url=URL.createObjectURL(blob)
            a.href=url
            a.click()
            URL.revokeObjectURL(a.href)
            row.downLoading = false;
            resolve(xhr.response);
          }else{
            //  this.$message.error('下载失败,请稍后再试!')
          }
        };
        xhr.onerror=(event)=>{
          if(xhr.status==0){
            console.log(132)
            this.$message.error('网络不可用!')
            obj.timeout='100'
            this.$store.commit("app/SETDOWNLIST", downList);
            row.downLoading = false;
          }
        }
        xhr.ontimeout=(e)=>{
          console.log(111)
        //  this.$message.error('下载失败,请稍后再试!')
          obj.timeout='100'
          downList.push({})
          downList.splice(downList.length-1,1)
          this.$store.commit("app/SETDOWNLIST", downList);
          row.downLoading = false;
         
        }
       
        xhr.send();
      });
    },
 
 
 
子组件进度条显示
<div class="downcon" v-show="show && this.list.length>0">
     <!-- <div class="downcon" v-show="show && this.list.length>0"> -->
    <div class="downgroup">
      <div class="downheader"></div>
      <div class="downmain" :class="small?'small':''" v-for="(item, index) in list" :key="index" v-if="item.rowName">
        <div class="closeProgress" @click="closeProgress(index)">X</div>
        <div  class="down-item">
          <!-- <i v-loading="item.loading" class="icon-loading" /> -->
          <span class="dan">{{ item.rowName}}</span>
         
          <span class="itemSize">{{item.size?((Number(item.size))/1024>1024?(Number(item.size))/1024/1024>1024?(Number(item.size))/1024/1024/1024>1024?((Number(item.size))/1024/1024/1024).toFixed(1)+'G':((Number(item.size))/1024/1024/1024).toFixed(1)+'G':((Number(item.size))/1024/1024).toFixed(1)+'M':((Number(item.size))/1024).toFixed(1)+'kb'):''}}</span>
         
        </div>
        <div>
            <el-progress :text-inside="true" :stroke-width="10" :percentage="item.percentage"></el-progress>
         
        </div>
        <div class="textDesc">
          <div class="textDescLeft loading"   v-if="Number(item.size)-(item.percentage/100)*item.size>0 && item.size && !item.timeout && item.timer!=0">
          <i class="el-icon-download"></i>
          正在下载,大约剩余{{(Number(item.size)-(item.percentage/100)*item.size)/1024>1024?(Number(item.size)-(item.percentage/100)*item.size)/1024/1024>1024?(Number(item.size)-(item.percentage/100)*item.size)/1024/1024/1024>1024?((Number(item.size)-(item.percentage/100)*item.size)/1024/1024/1024).toFixed(1)+'G':((Number(item.size)-(item.percentage/100)*item.size)/1024/1024/1024).toFixed(1)+'G':((Number(item.size)-(item.percentage/100)*item.size)/1024/1024).toFixed(1)+'M':((Number(item.size)-(item.percentage/100)*item.size)/1024).toFixed(1)+'kb'}}</div>
          <div class="textDescLeft success" v-if="Number(item.size)-(item.percentage/100)*item.size==0 && !item.timeout">
          <i class="el-icon-success"></i>
          下载完成</div>
         
          <div class="textDescRight">{{(item.percentage).toFixed(1)}}%</div>
          <div v-if="item.timeout || item.timer===0" class="err">
            <i class="el-icon-error"></i>
            下载失败&emsp;点击<el-button type="text" @click="aging(index)">重新下载</el-button></div>
        </div>
      </div>
      <!-- <i class="closeBtn" :class="small?'el-icon-crop':'el-icon-minus'" @click="onClosed"></i> -->
    </div>
  </div>
JS
export default {
  watch: {
    "store.state.app.downList":  {
      handler(val){
       this.list=val
       let i=0
       this.list.forEach(item=>{
         if(!item.rowName){
           i=i+1
         }
       })
       if(i==this.list.length && this.list.length!=0){
         this.show = false;
       }else{
         this.show = true;
       }
        // if (val && val.length>0) {
        //   this.show = true;
        // } else {
        //   this.show = false;
        // }
      },
      deep:true
    },
  },
  data() {
    return {
      flag:true,
      show: false,
      cancel: null,
      num:0,
      store: store,
      small: false
    };
  },
  computed: {
    list() {
      // console.log(store.state.app.downList)
      return store.state.app.downList || [];
    },
  },
  created() {
    console.log(this.list)
  },
  methods: {
    aging(index){
      let obj=this.list[index]
      this.$bus.$emit('glodAgain',index,obj)
    },
    onClosed() {
      this.small = !this.small;
    },
    closeProgress(index){
      this.list.forEach((item,i) => {
        if(i==index){
          this.$set(item,'rowName','')
        }
      });
      let i=0
       this.list.forEach(item=>{
         if(!item.rowName){
           i=i+1
         }
       })
       if(i==this.list.length && this.list.length!=0){
         this.show = false;
       }else{
         this.show = true;
       }
      this.$forceUpdate()
    }
  },
};
 
posted on 2022-05-24 09:29  林多多  阅读(104)  评论(0)    收藏  举报