Element-UI 上传组件自定义进度条

效果图:

在这里插入图片描述

步骤

首先,定义一个 el-upload 的组件,这里我选择的是「手动上传」模式:

<el-upload
    action=""
    :before-upload="beforeUpload"
    ref="uploadFile"
    :on-remove="removeFile"
    :file-list.sync="fileList">
    <el-button size="small" type="primary" plain>选取文件</el-button>
    <el-button size="small" type="success" @click="submit">上传文件</el-button>
</el-upload>

通过阅读 ElementUI 的源码,可以得知他的进度条以及右侧的小对勾分别是通过 file.percentage 和 file.status 来控制的。percentage 就是进度的百分比,是一个 0 ~ 100 的数字。status 有四种状态, ready:准备上传、uploading:正在上传、success:上传成功、fail:上传失败。
在上传文件时,我们不用 ElementUI 自带的上传方法,而是在 before-upload 中做处理,因此每次都返回 return false,以阻止调用自带的上传方法。

beforeUpload(newFile) {
    this.fileList.push({
        name: newFile.name,
        url: '',
        file: newFile,
        status: 'ready',
        percentage: 0
    });
    return false;
}

这里还发现了 ElementUI 的一个 BUG,就是点击删除文件时,文件在列表中消失了,但是在 this.fileList 中仍然存在,因此需要单独处理一下:

removeFile(file, fileList) {
    if (file.hasOwnProperty('file')) {
        for (let index in this.fileList) {
            if (this.fileList[index].uid === file.uid) {
                this.fileList.splice(index, 1);
                return;
            }
        }
    }
}

利用 axios 执行上传请求时,我们可以通过它提供的 onUploadProgress 方法获取到上传进度:

upload(url, params = {}, onUploadProgress, callback) {
	axios({
		headers: { 'X-Requested-With': 'XMLHttpRequest' },
		method: 'post',
		url: url,
		data: params,
		onUploadProgress,
	}).then((resp) => {
		callback({ status: 'success', data: resp });
	}).catch((error) => {
		callback({ status: 'error', error: error });
	});
}

接下来就是上传文件的操作了:

let readyFile = null;
for (const file of this.fileList) {
    if (file.status === 'uploading') {
        return this.$message.error('已有文件正在上传');;
    }
    if (file.status === 'ready') {
        readyFile = file;
    }
}
if (!readyFile) {
    return this.$message.error('请选取文件');
}
this.uploadingFile = readyFile;
this.uploadingFile.status = 'uploading';
const url = 'xxx';
let params = new FormData();
params.append('file', readyFile.file);
const onUploadProgress = (progressEvent) => {
    let percent = (progressEvent.loaded / progressEvent.total * 100 || 0);
    this.uploadingFile.percentage = percent;
};
this.upload(url, params, onUploadProgress, (resp: any) => {
    if (resp.status === 'success') {
        const data = resp.data.data;
        if (data.status === 'success') {
            this.$message({
                type: 'success',
                message: '上传成功',
            });
            this.uploadingFile.status = 'success';
        } else {
            this.uploadingFile.status = 'ready';
            this.uploadingFile.percentage = 0;
            this.$message.error(data.data.fail_message');
        }
    } else {
        this.uploadingFile.status = 'ready';
        this.uploadingFile.percentage = 0;
        const error = resp.error;
        this.$message.error(error.response.data.message);
    }
});
  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值