文件上传下载显示进度(vue)

时间:2024-01-18 18:43:44

编写了一个vue组件,可以实时显示文件上传和下载时候的进度

<template>
    <div v-show="circleProgress_wrapper_panel_statue"  class="circleProgress_wrapper_panel">
        <div class="circleProgress_wrapper">
            <div class="wrapper right">
                <div v-bind:style="{transform:'rotate('+leftDeg + 'deg)'}"  class="circleProgress rightcircle"></div>
            </div>
            <div class="wrapper left">
                <div v-bind:style="{transform:'rotate('+rightDeg + 'deg)'}"  class="circleProgress leftcircle"></div>
            </div>
         </div>
         <div class="backRect">
             <img src="../img/back.png" />
         </div>
     </div>
</template>
<script>
export default {
    data:function(){
        return {
            circleProgress_wrapper_panel_statue:false,
            leftDeg:0,
            rightDeg:0
        }
    },
    methods:{
        //上传文件
    loadFile:function (url, fileList,parm, suc) {
                let len = fileList.length,
                        _this = this;
                if(len == 0){
                    return;
                }
        this.showCircleProgressWrapperPanel();
        let formData = new FormData();
                for(let i = 0; i < len; i++){
                    formData.append("files"+i, fileList[i]);
                }
                for(let key in parm){
                    formData.append(key, parm[key]);
                }
        let xhr = new XMLHttpRequest();
        xhr.timeout = 15000;
        //xhr.responseType = "json";
        xhr.open('POST', url, true);
        xhr.onload = function (e) {
            if (this.status == 200 || this.status == 304) {
                suc(this.responseText);
            }
        };
        xhr.ontimeout = function (e) { alert("超时") };
        xhr.onerror = function (e) { alert("error:"+e) };
        xhr.upload.onprogress = function (e) {
            _this.updateCircleProgressWrapper(e.loaded, e.total);
        };
        xhr.send(formData);
    },
        //显示文件
    show:function (url, suc) {
                let _this = this;
        this.showCircleProgressWrapperPanel();
        let xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.responseType = "blob";
        xhr.onprogress = function (e) {
            _this.updateCircleProgressWrapper(e.loaded, e.total);
        };
        xhr.onload = function () {
            if (this.status === 200) {
                                let blob = this.response;
                                suc(blob);
            }
        }
        xhr.send();
    },
        test:function(){
            this.showCircleProgressWrapperPanel();
            let _this = this,
                    i = 0,
                    total = 10;
            window.interval = window.setInterval(function () {
                _this.updateCircleProgressWrapper(i, total);
                i = i + 1;
                if(i > total){
                    window.clearInterval(window.interval);
                }
            }, 100);
        },
    //根据上传字节数计算角度
    updateCircleProgressWrapper:function (loaded, total) {
        let deg = 360 * loaded / total;
        this.updateCircleProgressRotate(deg);
    },
    //隐藏滚动条
    hideCircleProgressWrapperPanel:function () {
                this.circleProgress_wrapper_panel_statue = false;
        this.setCircleProgressRotate(45, 45);
    },
    //显示滚动条
    showCircleProgressWrapperPanel:function () {
        this.circleProgress_wrapper_panel_statue = true;
    },
    //更新滚动条角度
    updateCircleProgressRotate:function (deg) {
        let defaultDeg = deg;
        if (deg <= 180) {
            deg = deg + 45;
            this.setCircleProgressRotate(deg, 45);
        } else {
            (deg > 360) ? deg = 360 : "";
            deg = deg - 180;
            deg = deg + 45;
            this.setCircleProgressRotate(225, deg);
        }
        if (defaultDeg == 360) {
            this.hideCircleProgressWrapperPanel();
        }
    },
    //设置滚动条角度
    setCircleProgressRotate:function(leftDeg, rightDeg) {
                this.leftDeg = leftDeg;
                this.rightDeg = rightDeg;
    }
    },
    mounted:function(){

    }
}
</script>
<style scoped>
    .circleProgress_wrapper_panel
    {
            position:fixed;
            top:0;
            left:0;
            right:0;
            bottom:0;
            background-color:rgba(0,0,0,0.8);
    }
    .circleProgress_wrapper
    {
            position:absolute;
            top:50%;
            left:50%;
            width: 100px;
            height: 100px;
            -webkit-transform: translate(-50%,-50%);
            transform: translate(-50%,-50%);
    }
    .wrapper{
            width: 50px;
            height: 100px;
            position: absolute;
            top:0;
            overflow: hidden;
    }
    .right{
            right:0;
    }
    .left{
            left:0;
    }
    .circleProgress{
            width: 80px;
            height: 80px;
            border:10px solid transparent;
            border-radius: 50%;
            position: absolute;
            top:0;
            -webkit-transform: rotate(45deg);
            transform: rotate(45deg);
    }
    .rightcircle{
            border-top:10px solid #767676;
            border-right:10px solid #767676;
            right:0;
            -webkit-transform: rotate(45deg);
            transform: rotate(45deg);
    }
    .leftcircle{
            border-bottom:10px solid #767676;
            border-left:10px solid #767676;
            left:0;
            -webkit-transform: rotate(45deg);
            transform: rotate(45deg);
    }
    .backRect
    {
         position:absolute;
         top:50%;
         left:50%;
         width:79px;
         height:79px;
         border:10px solid #e5e5e5;
         background-color:White;
         border-radius: 50%;
         -webkit-transform: translate(-50%,-50%);
         transform: translate(-50%,-50%);
         z-index:-1;
    }
    .backRect img
    {
        width:100%;
        position:absolute;
        top:50%;
        left:50%;
         -webkit-transform: translate(-50%,-50%);
         transform: translate(-50%,-50%);
    }
</style>

文件上传使用方法:

引入组件:import fileLoading from '../component/fileLoading.vue'

注册组件:

components: {
fileLoading:fileLoading
}

声明组件:<fileLoading ref="fileLoadingPonent"></fileLoading>

使用:

let fileData = [],
                        _this = this,
                        imgList = this.imgList,
                        len = this.imgList.length,
                        item = null;
                for(let i = 0; i < len; i++){
                    item = imgList[i];
                    fileData.push(item.data);//将多个文件对应的file对象放入数组
                }
                this.$refs.fileLoadingPonent.loadFile(Config.report,fileData,{content:this.reportContent},function(data){
                    let result = JSON.parse(data);
                    if(result.res == "1"){
                        _this.$store.commit('report/setReportContent',{value:""})
                        _this.$store.commit('report/clearImgList',{})
                        _this.clearIcon();
                    }else{
                        alert(result.msg);
                    }
                });

下载文件使用:

  使用场景:图片很大的时候,先加载缩略图,然后点击缩略图再加载大图

  引入组件:import fileLoading from '../component/fileLoading.vue'

  注册组件:

  components: {
    fileLoading:fileLoading
  }

  声明组件:<fileLoading ref="fileLoadingPonent"></fileLoading>

  使用:

  

loadBigImg:function(src,index,event){
      let _this = this;
      let NSrc = src.replace("_s","");//缩略图和大图的区别是缩略图在大图的名字后面多了_s,如:大图:name.jpg,对应的缩略图:name_s.jpg
      let NPath = Config.hostImg + NSrc;//大图的显示地址
      let target = event.currentTarget;
      this.$refs.fileLoadingPonent.show(NPath,function(blob){
        let imgEle = document.createElement("img");//创建新图片控件
        let parentNode = target.parentNode;
        parentNode.removeChild(parentNode.getElementsByTagName("img")[0]);//删除之前的缩略图
        imgEle.style.width = "100%";
        imgEle.onload = function (e) {
            window.URL.revokeObjectURL(imgEle.src); //释放。
        };
        imgEle.src = window.URL.createObjectURL(blob);  //有问题,将blob加载到img中 由于blob太大 会有性能影响 应该怎么在加载之后 如何释放呢:
        parentNode.appendChild(imgEle);
        //_this.$store.commit('details/changeImgList',{value:NSrc,index:index});
        target.style.display = "none";//隐藏提示点击加载文字
      });
    }