1.首先贴上转为Base64数据的方法:
//将图片的data返回给父组件registry.vue
const handleUpload = (file: any) => {
// 检查图片类型是否为 jpg 或 png
const isJpgOrPng =
file.raw.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
// 如果不是 jpg 或 png,则提示用户
const errorMsg = "图片类型只能为jpg/png";
ElMessage.error(errorMsg);
} else {
const reader = new FileReader();
reader.readAsDataURL(file.raw);
reader.onload = () => {
imgUrl.value = reader.result as any;
// 触发自定义事件,并将 Base64 编码传递给父组件
emit("update:modelValue", imgUrl.value);
};
}
};
我的代码略显繁琐是因为我的业务需要手动上传,所以中间多了一些代码,核心的是:
创建了一个 FileReader
对象:
const reader = new FileReader();
使用 readAsDataURL()
方法将文件读取为 Base64 编码的字符串: reader.readAsDataURL(file.raw);
readAsDataURL() 方法是一个异步方法,因此 onload 回调函数会在文件读取完成后被触发: reader.onload = () => {
reader.result
};
reader.result 中就是Base64 编码的字符。
2.从Base64编码读取到页面中
<template #column-flagImg="{ scope }">
<div class="flex items-center justify-center">
<el-image
class="h-9 min-w-12"
:src="scope.row.flagImg"
fit="cover"
/>
</div>
</template>
base64编码能直接被el-image标签读取为图片展示,所以只要从数据库中取出赋值给src就可以了,我这里是使用了el-table的插槽,看不懂的去官网看一下
3.将图片下载到本地并打包为压缩包
这里我们需要一个第三方的插件来完成打包,ts可以直接识别(如果识别不了,把VScode关掉重新打开)
import JSZip from "jszip";
//下载所有船籍图片
const handleDownload = async () => {
await service.ship.registry.list().then(async images => {
// 创建一个 ZIP 压缩包,并将图片文件添加到压缩包中
const zip = new JSZip();
for (let i = 0; i < images.length; i++) {
const image = images[i];
if (image.flagImg) {
//没有图片的国旗不被下载
const data = image.flagImg?.split(",")[1]; // 获取 base64 编码的数据
const binaryData = base64ToBinary(data as any); // 将 base64 编码的数据转换为二进制数据
zip.file(
image.mid +
"-" +
image.eCountry +
"-" +
image.cCountry +
"-" +
image.abbreviate +
".jpg",
binaryData,
{ binary: true }
); //下载的图片名称为编码-国家名-中文名-缩写.jpg,例如412-China-中国-CHN.jpg
}
}
// 将压缩包转换为 Blob 对象,并创建下载链接
const blob = await zip.generateAsync({ type: "blob" });
console.log(blob);
const url = URL.createObjectURL(blob);
// 创建 a 标签,并设置 download 属性,将压缩包下载到本地
const a = document.createElement("a");
a.href = url;
a.download = "images.zip";
document.body.appendChild(a);
a.click();
// 释放下载链接
URL.revokeObjectURL(url);
});
};
const base64ToBinary = (base64: string) => {
const binaryStr = window.atob(base64);
const len = binaryStr.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryStr.charCodeAt(i);
}
return bytes;
};
handleDownload是绑定在按钮上的触发打包下载的方法
代码解释的还是比较详细的,主要分为两个步骤
第一步:
创建JSZip对象读取文件,并把压缩包的下载绑定到一个url上
第二步:
js代码中创建一个a链接,将url绑定到a链接上,将a链接塞入document上,模拟点击下载
还有要注意的一点,数据库中存入base64字符串的字段只要要使用text