使用方法:
api方法
api | 描述 | 默认 |
---|---|---|
disabled | 是否可上传 | true |
show | 是否显示支持的格式并切换导入模式 | true |
buttonType | 上传按钮的格式 | “” |
title | 上传按钮的文字 | 上传文件 |
action | 上传接口 | /api/gov/upload/fileUpload |
maxNum | 上传的最大数量 | 1 |
types | 上传文件的格式 | [".doc",".docx",".pdf",".xls",".xlsx",".rar",".csv", “.zip”,".jpg",".jpeg",".gif",".png",".rar",".zip",".7z",".tar",] |
isLt | 上传文件的大小 | 10M |
values | 用于编辑回显 | [] |
params | 上传接口要传入的其他数据 | {} |
ref链上的方法
获取方式 | 描述 |
---|---|
.fileList | 要保存的文件列表 |
.addFileList | 所有添加的文件列表 |
.handleClearList() | 清除保存文件列表的方法 |
组件中使用上传组件的时候可以封装的一些方法
实例默认ref等于myUpload
/*
数据处理的方法
*/
handleRemoveFile() {
//处理上传文件新增、删除、保存
this.newAddFileList = []; //储存所有添加的文件列表
this.newFileList = []; //储存所有要保存文件的列表
this.removeFile = []; //储存所有要删除文件的列表
//获取所有上传的文件列表
this.newAddFileList = this.$refs.myUpload.addFileList;
//获取所有要保存文件的列表
this.$refs.myUpload.fileList.map((item) => {
this.newFileList.push(item.url ? item.url : item.response.data);
});
//获取所有最后要删除文件的列表
let removeFile = [];
this.newAddFileList.map((item) => {
if (this.newFileList.indexOf(item) == "-1") {
removeFile.push(item);
}
});
this.values.map((item) => {
if (this.newFileList.indexOf(item) == "-1") {
removeFile.push(item);
}
});
this.removeFile = removeFile;
},
组件的封装:
<template>
<div class="upload-box">
<a-upload
name="file"
:multiple="true"
:action="action"
:headers="headers"
:file-list="fileList"
@change="handleUploadChange"
:beforeUpload="beforeUpload"
:disabled="disabledBotton || disabled"
:data="{
...params,
}"
>
<a-button :disabled="disabledBotton || disabled" :type="buttonType">
<a-icon type="upload" /> {{ title }}
</a-button>
</a-upload>
<slot name="alert"></slot>
<span class="type-box" v-if="show">
<span>支持格式:</span>{{ types.join(" ") }}
</span>
</div>
</template>
<script>
import { getToken } from "@/utils/auth.js";
import { handleCompressImg } from "@/utils/compressImg.js";
export default {
props: {
disabled: {
type: Boolean,
default: () => {
return true;
},
},
show: {
type: Boolean,
default: () => {
return true;
},
},
buttonType: {
type: String,
default: () => {
return "";
},
},
title: {
type: String,
default: () => {
return "上传文件";
},
},
action: {
type: String,
default: () => {
return "/api/gov/upload/fileUpload";
},
},
maxNum: {
type: Number,
default: () => {
return 1;
},
},
types: {
type: Array,
default: () => {
return [
".doc",
".docx",
".pdf",
".xls",
".xlsx",
".rar",
".csv",
".zip",
".jpg",
".jpeg",
".gif",
".png",
".rar",
".zip",
".7z",
".tar",
];
},
},
isLt: {
type: Number,
default: 10,
},
values: {
type: Array,
},
params: {
type: null,
default: () => {
return {};
},
},
},
data() {
return {
fileList: [],
addFileList: [],
headers: {
token: getToken(),
},
disabledBotton: false,
};
},
watch: {
values: function () {
this.addFileList = [];
if (this.values.length > 0) {
let i = 0;
this.values.map((item) => {
i++;
this.fileList.push({
uid: i,
name: i + ".文件" + item.substring(item.lastIndexOf(".")),
status: "done",
url: item,
});
});
}
},
},
created() {
this.addFileList = [];
if (this.values.length > 0) {
let i = 0;
this.values.map((item) => {
i++;
this.fileList.push({
uid: i,
name: i + ".文件" + item.substring(item.lastIndexOf(".")),
status: "done",
url: item,
});
});
}
},
methods: {
handleClearList() {
this.fileList = [];
},
handleUploadChange(info) {
if (info.file.status) {
// this.disabledBotton = true;
let fileList = [...info.fileList];
if (fileList.length >= this.maxNum + 1) {
fileList = fileList.slice(1);
}
//
fileList = fileList.map((file) => {
if (file.response) {
file.url = file.response.url;
}
return file;
});
this.fileList = fileList;
}
if (info.file.status === "done") {
if (!this.show) {
//导入模式
this.fileList = [];
this.$emit("uploads");
this.$message.success(`${info.file.response.msg}`);
} else {
console.log(info.file.response);
this.addFileList.push(info.file.response.data);
this.$message.success(`${info.file.name} 文件上传成功`);
}
// this.disabledBotton = false;
// this.$emit("change", this.fileList,'up');
// this.$emit("change", this.addFileList,'add');
} else if (info.file.status === "error") {
this.$message.error(`${info.file.name} 文件上传失败`);
if (!this.show) {
//导入模式
this.fileList = [];
}
}
},
beforeUpload(file, fileList) {
return new Promise((resolve, reject) => {
let imgType = [".png", ".jpg", ".jpeg"];
console.log("before", fileList);
const max = this.fileList.length >= this.maxNum ? false : true;
// const max = this.fileList.length > this.maxNum ? false : true;
if (!max) {
this.$message.error(`最多上传${this.maxNum}个文件`);
reject();
}
// console.log(file.name.substring(file.name.lastIndexOf(".")));
const isJpgOrPng =
this.types.indexOf(file.name.substring(file.name.lastIndexOf("."))) !=
"-1"
? true
: false;
if (!isJpgOrPng) {
this.$message.error("只能上传" + this.types.join(","));
reject();
}
const isLt10M = file.size / 1024 / 1024 < this.isLt;
if (!isLt10M) {
this.$message.error("文件不能大于" + this.isLt + "MB!");
reject();
}
if (
imgType.indexOf(file.name.substring(file.name.lastIndexOf("."))) !=
"-1" &&
file.size / 1024 / 1024 > 5
) {
this.$message.error("图片不能大于5MB!");
reject();
}
this.disabledBotton = false;
if (
imgType.indexOf(file.name.substring(file.name.lastIndexOf("."))) !=
"-1"
) {
handleCompressImg(file).then((res) => {
console.log(file, res);
res.uid = file.uid;
resolve(res);
});
} else {
resolve(file);
}
});
// return isLt10M && isJpgOrPng && max;
},
},
};
</script>
<style lang="less" scoped>
.upload-box {
display: inline-block;
width: 100%;
position: relative;
.type-box {
display: inline-block;
font-size: 12px;
line-height: 14px;
padding-left: 60px;
position: relative;
padding-top: 5px;
span {
position: absolute;
left: 0px;
}
}
}
</style>
图片压缩方法
// 压缩图片
export function handleCompressImg(file) {
let Orientation;
if (/^image/.test(file.type)) {
return new Promise((resolve) => {
// 创建一个reader
let reader = new FileReader();
// 将图片转成 base64 格式
reader.readAsDataURL(file);
// 读取成功后的回调
reader.onloadend = function (e) {
let img = new Image();
let result = e.target.result;
img.src = result;
// 判断图片是否大于100K,是就压缩图片,反之直接上传
// if (result.length <= (100 * 1024)) {
// console.log('图片小于100k') // 不对图片进行压缩操作
// return resolve(file)
// } else {
img.onload = function () {
return resolve(dataURLtoFile(compress(img, Orientation), file.name));
};
// }
};
});
}
}
function compress(img, Orientation) {
// 压缩操作
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
// 瓦片canvas
let tCanvas = document.createElement("canvas");
let tctx = tCanvas.getContext("2d");
let initSize = img.src.length;
let width = img.width;
let height = img.height;
// 如果图片大于四百万像素,计算压缩比并将大小压至400万以下
let ratio; //像素压缩
if ((ratio = (width * height) / 2000000) > 1) {
console.log("大于400万像素");
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
// 铺底色
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 如果图片像素大于100万则使用瓦片绘制
let count;
if ((count = (width * height) / 1000000) > 1) {
console.log("超过100W像素");
count = ~~(Math.sqrt(count) + 1); // 计算要分成多少块瓦片
// 计算每块瓦片的宽和高
let nw = ~~(width / count);
let nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(
img,
i * nw * ratio,
j * nh * ratio,
nw * ratio,
nh * ratio,
0,
0,
nw,
nh
);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
// 修复ios上传图片的时候 被旋转的问题
if (Orientation !== "" && Orientation !== 1) {
switch (Orientation) {
case 6: // 需要顺时针(向左)90度旋转
this.rotateImg(img, "left", canvas);
break;
case 8: // 需要逆时针(向右)90度旋转
this.rotateImg(img, "right", canvas);
break;
case 3: // 需要180度旋转
this.rotateImg(img, "right", canvas); // 转两次
this.rotateImg(img, "right", canvas);
break;
}
}
// 进行最小压缩
let ndata = canvas.toDataURL("image/jpeg", 0.4);
console.log("压缩前:" + initSize);
console.log("压缩后:" + ndata.length);
console.log(
"压缩率:" + ~~((100 * (initSize - ndata.length)) / initSize) + "%"
);
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return ndata;
}
// base64转化成文件对象格式
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(",");
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
// 转换成file对象
return new File([u8arr], filename, { type: mime });
}
自己封装的组件,有不足的地方希望各位大佬补充,可评论留言