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 || '文件上传失败',
});
}
});
},