vue element-ui,上传文件加载进度条显示效果(使用定时器实现源码分享)

上传文件效果如图:

 

父组件相关代码

html

 <drag-upload
            ref='mychild'
            action="//接口相关地址" 
            v-model="versionwareList"
            @submitUploadParent='formSubmit'
            @input='delUpload'
            :autoUpload="autoUpload"
            :visible="visible"
            :disabled="disabled"
          />

js

 handleSubmit() {
        this.$refs.form.validate(async (valid) => {
          if (valid) {
            this.submitLoading = true;
            this.disabled = true;
            //数据校验成功,上传文件
            this.$refs.mychild.submitUpload();
            // this.submitLoading = false;
          } else {
            this.$message.error('请按照正确格式填写');
          }
        });
      },


 

 

 

子组件代码

 

<template>
  <!-- 文件拖拽上传 -->
  <div>
    <el-upload
      class="drag-upload"
      :action="action"//接口地址
      :name="name"//上传的文件字段名
      :data="otherParams"//上传时附带的额外参数
      :visible="visible"//根据父组件传值
      ref="upload"
      drag//是否启用拖拽上传
      :headers='xHeaders'//设置上传的请求头部
      :limit="limit"//最大允许上传个数
      :file-list="value"//上传的文件列表
      :auto-upload="autoUploadVal"//是否自动上传文件
      :before-upload="beforeUpload"//上传文件之前的钩子
      :before-remove="beforeRemove"//删除文件之前的钩子
      :on-success="handleSuccess"//文件上传成功时的钩子
      :on-progress="onProgress"//文件上传时的钩子,进度条加载
      :on-remove="handleRemove"//文件列表移除文件时的钩子
      :on-preview="handlePreview"//点击文件列表中已上传的文件时的钩子
      :disabled="disabled"//是否禁用
    >
      <el-progress type="circle" v-if="loading" :percentage="percentage" :color="colors" class="progress"></el-progress>
      <i class="drag-upload__icon" :class="loading ? '' : 'el-icon-upload' "></i>
      <p class="drag-upload__text" v-show="!loading">点击或直接将文件拖到此处上传</p>
      <p class="drag-upload__tip" v-show="!loading">文件大小不能超过{{sizeLimit}}MB!{{tip}},只允许上传{{limit}}个文件</p>
    </el-upload>
  </div>

</template>

<script>
  import axios from 'axios';
  import Vue from 'vue';
  export default {
    props: {
      // 文件列表
      value: {
        type: Array,
        default () {
          return [];
        }
      },
      autoUpload:{
        type: String,
        default: 0
      },
      //文件个数
      limit:{
        type: Number,
        default:1,
      },
      //上传地址
      action: {
        required: true,
        type: String,
        default: '',
      },
      // 对应inpu控件的name属性,后端依据这个字段获取文件。
      name: {
        type: String,
        default: 'file'
      },
      disabled:{
        type: Boolean,
        default: false
      },
      // 文件的大小限制,单位为MB
      sizeLimit: {
        type: Number,
        default: 1000
      },
      // 提示信息
      tip: {
        type: String,
        default: ''
      },
      visible: {
        type: Boolean,
        default: false
      }
    },
    watch: {
      visible(value) {
        if (value) {
        }else{
          clearInterval(this.interval);
          this.loading = false;
        }
      }
    },
    data() {
      return {
        loading: false,
        otherParams:{
          //根据自己接口要求设置
        },
        xHeaders:{
          //根据自己接口要求设置
        },
        autoUploadVal:this.autoUpload=='1'?true:false,
        isChangeFlag:false,
        percentage:0,//加载进度条初始值
        colors:[
          {color: '#f56c6c', percentage: 20},
          {color: '#e6a23c', percentage: 40},
          {color: '#5cb87a', percentage: 60},
          {color: '#1989fa', percentage: 80},
          {color: '#6f7ad3', percentage: 100}
        ],
        interval:0,//加载的定时器
        timeStop:0,//加载成功停止的定时器
      }
    },
    methods: {
       submitUpload() {
        let uoloadFilesData = this.$refs.upload.uploadFiles
        if(uoloadFilesData.length == 0){
          let res={
            data:''
          }
          this.$emit('submitUploadParent',res);
        }else{
          if(uoloadFilesData[0].status === 'success'){
            uoloadFilesData[0].data = uoloadFilesData[0].name
            this.$emit('submitUploadParent',uoloadFilesData[0]);
          }else{
            this.$refs.upload.submit();
          }
        }
      },
      abort(){
        this.$refs.upload.abort();
      },
      //进度条
      onProgress(e, file, v) {
        let that = this;
        let endPro = 95;
        that.loading = true;
        that.interval = setInterval(function () {
          if (that.percentage < endPro) {
            that.percentage++;
          }
        },500)
      },
      beforeUpload(file) {
        const limit = file.size / 1024 / 1024 < this.sizeLimit;
        if (!limit) {
          this.$message.error(`上传的文件小不能超过 ${this.sizeLimit}MB!`);
        }
        if (limit) {
          this.loading = true;
        }
        return limit;
      },
      beforeRemove(file, fileList) {
        return this.$confirm(`确定删除“${ file.name }”?`);
      },
      handleSuccess(res, file, fileList) {
        //上传成功,给个加载100的效果
        let that = this;
        that.percentage = 100;
        clearInterval(that.interval)
        that.timeStop=setTimeout(() => {
          that.loading = false;
          that.percentage=0;
          clearTimeout(that.timeStop)
          //根据实际开发情况处理响应
          if (true) {
            //文件上传成功,返回状态数据
            that.$emit('submitUploadParent',res);
          } else {
            that.$message.error(res.message || '上传失败');
          }
        }, 100);
      },
      handleRemove(file, fileList) {
        //删除列表选项,需要停止定时器及相关参数
        clearInterval(this.interval)
        this.percentage = 0;
        this.loading = false;
        this.$emit('input', fileList);
      },
      handlePreview(file) {
        window.open(file.url);
      }
    },
  }
</script>

<style lang="scss" scoped>
  .drag-upload {
    .drag-upload__icon {
      font-size: 40px;
      line-height: 40px;
      color: var(--theme);
      margin: 0;
    }

    .drag-upload__text {
      line-height: 20px;
      margin-bottom: 6px;
    }

    .drag-upload__tip {
      font-size: 12px;
      line-height: 20px;
      color: $auxiliary-text-color;
    }
  }
</style>

<style lang="scss">
  .drag-upload {
    .el-upload {
      width: 100%;
    }
    .el-upload-dragger {
      width: 100%;
      min-height: 140px;
      height: 100%;
      padding: 20px 1em;
    }
    .el-progress{
      display: none;
    }
    .progress.el-progress{
      display: inline-block;
    }
  }
</style>

 

posted @ 2020-04-05 23:29  嘉煠  阅读(7320)  评论(0编辑  收藏  举报