此示例为electron+vue2,需要vue3的宝子可自行转换,流程上没有区别
electron:
1、利用dialog.showOpenDialog的API弹出一个窗口,并确认按钮文字,窗口title,限制类型等等
2、利用fs.readFile读取该文件路径的文件流格式
3、利用fs.stat读取文件大小,并限制文件大小
4、拿取名称,路径,文件流,包装成一个对象传给vue项目
var fileReadTwoCode = function (path) {
return new Promise(function (resolve, reject) {
fs.readFile(path, function (err, stat) {
resolve(stat)
})
})
}
var fileStat = function (path) {
return new Promise(function (resolve, reject) {
fs.stat(path, function (err, stat) {
resolve(stat.size)
})
})
}
// 选择文件路径
ipcMain.handle('select-file', async (event, arg) => {
const info = await dialog.showOpenDialog({
properties: ['openFile'],
title: arg.title,
defaultPath: arg.defaultPath,
filters: arg.filters,
buttonLabel: "确认选择",
}).then(async result => {
if (result.canceled) {
return ''
}
// 读文件流格式
const data=await fileReadTwoCode(result.filePaths[0]);
// 读取文件大小
const size=await fileStat(result.filePaths[0]);
// 限制5M
if(size/ 1024 / 1024 > 5){
return '图片过大'
}
// 拿取名称,路径,文件流,传给vue项目
const arr=result.filePaths[0].split('\\');
let resultData={
data,
path: result.filePaths[0],
name:arr[arr.length-1]
}
return resultData
}).catch(error => {
return ''
})
return info
});
vue:
1、页面
<el-form-item label="问题截图" class="content-img">
<!-- 上传成功的图片回显 -->
<div
v-for="(item, index) in fankuiForm.impagePaths"
class="avatar-uploader"
@click="handleSelectImgFile"
>
<!-- 加载态 -->
<i v-if="item.includes('fkuImgLoading')" class="el-icon-loading"></i>
<!-- 图片 -->
<img
v-if="!item.includes('fkuImgLoading')"
:src="$config.baseUrl + item"
class="avatar"
/>
<!-- 划过删除 -->
<div class="delDiv" @click="delImgPath(index)">
<i class="el-icon-delete avatar-uploader-icon"></i>
</div>
</div>
<!-- 少于5张图,结尾的添加 -->
<div
v-if="fankuiForm.impagePaths.length < 5"
class="avatar-uploader"
@click="handleSelectImgFile"
>
<i class="el-icon-plus avatar-uploader-icon"></i>
</div>
<!-- 等于五张图,结尾的文案提醒 -->
<div v-if="fankuiForm.impagePaths.length >= 5">
<span class="content-span">*最多添加五张</span>
</div>
</el-form-item>
2、变量声明
data() {
return {
fankuiForm: {
impagePaths: [],
},
};
},
3、方法
handleSelectImgFile() {
// 调用壳的方法
this.$ipcApi
.send("select-file", {
title: "选择图片",
defaultPath: "",
filters: [
{
name: "image",
extensions: [
"jpg",
"jpeg",
"png",
"gif",
"bmp",
"JPG",
"JPEG",
"PNG",
"GIF",
"BMP",
],
},
],
})
.then(async (result) => {
// 把blob格式的文件流转换成file格式
const file = this.Blob2ImageFileForWXBrowser(result);
// 声明formData
var formData = new FormData();
// 把file放入formData
formData.append("file", file);
// electron有返回结果 不是点击取消或者关闭
if (result) {
// electron返回图片过大 则报错结束
if (result == "图片过大") {
this.$message.error("图片不能超过5MB!");
return;
}
// 显示加载态
this.fankuiForm.impagePaths.push("fkuImgLoading");
// 请求接口,带入formData
axios
.post("/feedback/batchUploadImage", formData, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((res) => {
console.log(res);
// 删除加载态 回显图片
this.fankuiForm.impagePaths.pop();
this.fankuiForm.impagePaths.push(res.data.body.imageVo.impagePaths);
})
.catch((res) => {
console.log(res);
this.$message.error(res.data.header.resultMsg);
});
}
});
},
// 把blob格式的文件流转换成file格式
Blob2ImageFileForWXBrowser(result) {
const file = new window.File([result.data], result.name, {
type: "png",
});
return file;
},