封装文件上传组件

1、创建公共组件

<template>
    <el-upload
        ref="upload"
        :class="className"
        :disabled="disabled"
        :action="action"
        :headers="uploadHeaders"
        :accept="accept"
        :multiple="multiple"
        :show-file-list="showFileList"
        :auto-upload="autoUpload"
        :before-upload="uploadBefore"
        :on-change="uploadChange"
        :on-success="uploadSuccess"
        :on-error="uploadError"
        :on-progress="uploadProgress"
        :on-remove="uploadRemove"
        :on-exceed="uploadExceed"
        :on-preview="uploadPreview"
        :file-list="fileList"
        :limit="limit"
        :data="uploadParams"
        style="width: 100%"
        :http-request="httpRequest"
    >
        <el-button :type="btnType" :size="btnSize" :disabled="disabled" :icon="icon">{{ disabled ? btnTextDisabled : btnText }}</el-button>
        <div v-if="showTip" slot="tip" class="el-upload__tip">{{ showTip }}</div>
    </el-upload>
</template>

<script>
import { getToken } from '@/utils/auth';
import { base64ToBlob } from '@/utils/index';

export default {
    props: {
        className: {
            type: String,
            default: '',
        },
        btnType: {
            type: String,
            default: '', // primary / success / warning / danger / info / text
        },
        btnSize: {
            type: String,
            default: 'small', // medium / small / mini
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        action: {
            type: String,
            default: '/api/net/fdfs/file/upload',
        },
        accept: {
            type: String,
            default: '.pdf,.png,.jpg', // doc,docx,xls,xlsx,txt,pdf,jpg,png
        },
        multiple: {
            type: Boolean,
            default: false,
        },
        showFileList: {
            type: Boolean,
            default: true,
        },
        autoUpload: {
            type: Boolean,
            default: true,
        },
        limit: {
            type: Number,
            default: 1,
        },
        fileList: {
            type: Array,
            default: () => [],
        },
        btnText: {
            type: String,
            default: '点击上传',
        },
        btnTextDisabled: {
            type: String,
            default: '点击下载',
        },
        showTip: {
            type: String,
            default: '',
        },
        //返回url是否加密
        encrypt: {
            type: Boolean,
            default: false,
        },
        icon: {
            type: String,
            default: '',
        },
        uploadParams: {
            type: Object,
            default: () => {
                return {};
            },
        },
        httpRequest: Function,
    },
    data() {
        return {
            uploadHeaders: {},
            token: '',
        };
    },
    created() {
        const TOKEN = getToken();
        this.token = TOKEN;
        this.uploadHeaders = {
            Authorization: TOKEN,
            responseType: 'blob',
            ContentType: 'application/vnd.ms-excel;charset=utf-8',
        };
    },
    methods: {
        // 上传文件 之前
        uploadBefore(file) {
            const size = file.size / 1024 / 1024 < 5;
            if (!size) {
                this.$message.error('文件大小不能超过 5MB!');
            }
            this.$emit('upload-before', file);
            // 取消文件上传校验;
            return size;
        },
        // 上传文件 个数超出上限
        uploadExceed(files, fileList) {
            this.$message.warning(`超出上传个数`);
        },
        // 上传文件 成功
        uploadSuccess(response, file, fileList) {
            this.$emit('upload-success', response, file, fileList);
        },
        // 上传文件 失败
        uploadError(err, file, fileList) {
            this.$emit('upload-error', err, file, fileList);
        },
        // 上传时
        uploadProgress(event, file, fileList) {
            this.$emit('upload-progress', event, file, fileList);
        },
        // 上传文件 移除
        uploadRemove(file, fileList) {
            this.$emit('upload-remove', file, fileList);
        },
        // 上传文件 点击列表文件时(下载)
        uploadPreview(file) {
            //文件上传存在
            if (file.status == 'success' && file.response.rel) {
                //创建a标签,
                let a = document.createElement('a');
                let mime = null;
                //判断文件的回显是从远程获取,还是从本地获取的
                if (file.size) {
                    //从本地回显的
                    a.download = `${file.name}`;
                } else {
                    //从远端回显 分为url加密和不加密俩种情况
                    if (this.encrypt) {
                        //进行加密了,第一种情况是通过
                        mime = file?.response?.data?.type;
                    } else {
                        let fileUrl = file?.response?.data?.fileUrl;
                        let index = fileUrl.lastIndexOf('.') + 1;
                        mime = fileUrl.substring(index);
                    }
                    a.download = `${file.name}.${mime}`;
                }
                let blob = base64ToBlob(file?.response?.data?.picBase64, mime);
                a.href = URL.createObjectURL(blob);
                a.click();
                URL.revokeObjectURL(a.href);
            }
        },
        // 上传文件 改变
        uploadChange(file, fileList) {},
    },
};
</script>

<style lang="scss" scoped>
.el-upload__tip {
    color: #d2000e;
    letter-spacing: 1px;
    line-height: 1;
    transform: scale(0.9);
    margin-top: 0;
    position: relative;
    left: -5px;
}
</style>

2、定义base64ToBlob 方法 

// base64 转 blob对象
export function base64ToBlob(base64, mimeType) {
    let bytes = window.atob(base64);
    let ab = new ArrayBuffer(bytes.length);
    let ia = new Uint8Array(ab);
    for (let i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i);
    }
    return new Blob([ab], { type: mimeType });
};

3、使用方式

  • 引入组件
<UploadFile
    ref="UploadFile"
    className="upload"
    btnText="上传"
    @upload-before="file => uploadBefore(file, ID)"
    @upload-success="uploadSuccess"
    @upload-error="uploadError"
    @upload-progress="uploadProgress"
    @upload-remove="uploadRemove"
    :uploadParams="uploadData.params"
    :action="uploadData.action"
    :accept="uploadData.accept"
    :btnType="uploadData.btnType"
    :btnSize="uploadData.btnSize"
    :showFileList="false"
    :httpRequest="httpRequest"
/>
  • 定义data参数
uploadData: {
    action: '/api/net/api/receiptInformation/generate/push', // 上传地址
    accept: '.png,.jpg,.pdf', // 文件格式
    btnType: 'text', // 按钮类型
    btnSize: 'mini',
    params: {
        contractOrderId: '',
    },
},
uploadProcess: null,
formData: null, // 传递参数
  • 定义方法
// 导入前-传递参数
uploadBefore(file, id) {
    this.formData = new FormData();
    this.formData.append('file', file);
    this.formData.append('contractOrderId', id);
},

// 导入-成功
uploadSuccess(response, file, fileList) {
    if (this.uploadProgress) {
        this.uploadProgress.close();
    }
    this.$notify({
        type: 'success',
        title: '提示',
        message: '文件上传成功',
    });
    if (this.$refs['UploadFile'] !== undefined) {
        this.$refs['UploadFile'].$refs['upload'].clearFiles();
    }
},

// 导入-错误
uploadError(err, file, fileList) {
    if (this.uploadProgress) {
        this.uploadProgress.close();
    }
    if (this.$refs['UploadFile'] !== undefined) {
        this.$refs['UploadFile'].$refs['upload'].clearFiles();
    }
    this.$notify({
        type: 'error',
        title: '提示',
        message: '文件上传失败',
    });
},
 // 导入时
uploadProgress(event, file, fileList) {
    this.uploadProgress = this.$loading({
        lock: true,
        text: '文件上传中,请稍后……',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
        customClass: 'loading-white',
    });
},
// 导入失败
uploadRemove(file, fileList) {
    this.uploadProgress.close();
    if (this.$refs['UploadFile'] !== undefined) {
        this.$refs['UploadFile'].$refs['upload'].clearFiles();
    }
},
// 自定义上传请求
httpRequest(params) {
    this.uploadProgress = this.$loading({
        lock: true,
        text: '文件上传中,请稍后……',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
        customClass: 'loading-white',
    });
    fetch({
        url: '/net/api/receiptInformation/generate/push',
        method: 'post',
        data: this.formData,
        headers: { 'Content-Type': 'multipart/form-data' },
    }).then(res => {
        this.formData = null;
        this.uploadDisabled = false;
        this.uploadProgress.close();
        if (this.$refs['UploadFile'] !== undefined) {
            this.$refs['UploadFile'].$refs['upload'].clearFiles();
        }
        if (res.rel) {
            this.$notify({
                type: 'success',
                title: '提示',
                message: res.data || '文件上传成功',
            });
            this.handleSearch();
        } else {
            this.$notify({
                type: 'error',
                title: '提示',
                message: res.data || '文件上传失败',
            });
        }
    });
},

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值