最近在用vue重写项目的时候,遇到了上传文件显示进度的问题,进过看axios文档,最终实现了此功能,意外发现文档中有取消的接口,故此又做了取消请求的功能,特此记录.如有不对的地方,欢迎指正.

知识点:axios的onUploadProgress配置项,用于进度条的实现;axios的cancelToken,用于取消请求的实现

详情可查看axios的文档:https://www.kancloud.cn/yunye/axios/234845

实现代码:

//global.js,将这个方法抽到公共方法里面,在需要用的组件内可以直接使用,需要在main.js中引入global.js
function uploadFile (url,payload,cancelToken,callback1) {
    return new Promise(function(resolve,reject){
        axios({
            url:url,
            method:'post',
            data:payload,
            onUploadProgress:function(progressEvent){
                if(progressEvent.lengthComputable){ callback1(progressEvent); }
            },
            cancelToken: cancelToken
        }).then(res =>{
            resolve(res);
            })
            .catch(thrown => { 
                if (axios.isCancel(thrown)) {
                    reject('-2')

              } else {
                reject(thrown)
              }
            })
    })
  
}

export default{
    install: function(Vue){
        Vue.prototype.uploadFile = (url,payload,cancelToken,callback1) => uploadFile (url,payload,cancelToken,callback1);
    }
};

组件代码:

<!--在需要的组件内引入此组件,这个组件需要传递一个属性:uploadPercent,和一个方法:cancelRequest--> 
<progress-bar class="progress-bar" :uploadPercent="uploadPercent" 
                            v-show="uploadPercent && uploadPercent != 100 "
                            @cancelRequest="cancelRequest"></progress-bar>
<!--数据-->
data(){
    return {
            fileName:'',
            uploadPercent:0,
            source:this.axios.CancelToken.source(),
        }
    },

<!--js方法-->
importFile() {
            const _this = this;
            _this.source = this.axios.CancelToken.source();

            if(!_this.$refs.selectFile.files[0]){
                alert('请选择文件');
                return
            }
            let fileData = new FormData();

            fileData.append('uploadfile', _this.$refs.selectFile.files[0]);
            
            let url = '填写你自己的url';
            this.uploadFile(url,fileData,_this.source.token, (res) =>{
                let loaded = res.loaded,
                total = res.total;
                _this.$nextTick(() =>{
                    _this.uploadPercent = Math.floor(loaded/total*100)>1? Math.floor(loaded/total*100):1;
                    })
                    }).then((res)=>{
                        if(res.data.code == 0){
                            alert('上传成功');
                            _this.uploadPercent = 0;
                        }
                    }, (rej)=>{
                        if( rej == -2){
                            alert('取消上传成功')
                        } else {
                            alert('上传失败')
                        }
                    })
        },
cancelRequest(){
    if(confirm('确认取消此次上传?')){
        this.source.cancel('Operation canceled by the user.');
        this.uploadPercent = 0;
    }
},

progress-bar组件实现:

<template>
<div class="progress-bar">
    <div class="progress-percent" :style="{width:uploadPercent+'%'}"></div>
    <div class="tip" :style="{left:uploadPercent+'%'}" 
      v-show="uploadPercent && uploadPercent !=100"
        >{{uploadPercent+'%'}}
    </div>
    <div class="cancel-btn" @click="cancelRequest()">×</div>
</div>
</template>

<script>

export default {
    name:'progress-bar',
    props:{
        uploadPercent:Number
    },
    methods: {
        cancelRequest(){
            this.$emit('cancelRequest');
        }
    }
}
</script>

<style scoped>
样式自己DIY
</style>

 

Logo

前往低代码交流专区

更多推荐