前文
项目需要保存数据,一开始用的 localStorage 做数据缓存,因其缓存容量有限(5M)以及其他原因,需要保存成文件形式。
我使用node.js的 fs 模块做数据的文件化写入,读取以及删除功能。
完整代码
主进程
background.js
const { app, protocol, BrowserWindow, ipcMain } = require('electron')
const { createProtocol } = require('vue-cli-plugin-electron-builder/lib')
const fs = require('fs');
const path = require('path');
// 指定目录(客户端根目录)
let specifiedDirectory = '';
if(process.platform=='win32'){//Windows
specifiedDirectory = 'D:\\myProject\\allData\\';
}else{//linux('linux'),macOS('darwin')
specifiedDirectory = '/home/myProject/allData/';
}
// 确保目录存在
if (!fs.existsSync(specifiedDirectory)) {
fs.mkdirSync(specifiedDirectory, { recursive: true });// 使用recursive选项可以创建嵌套目录
}
// 写入数据文件
ipcMain.handle('write-file', async (event, options) => {
try {
// options 应该包含 data 和文件名
const { data, filename } = options;
const filePath = path.join(specifiedDirectory, filename);
return new Promise((resolve, reject) => {
fs.writeFile(filePath, JSON.stringify(data), function(err){
if(err) return reject({ok: false, msg: err.message});
resolve({ok: true, msg: "写入成功"});
})
})
} catch (error) {
console.error('background.js写入数据文件时出错:', error);
return Promise.reject({ok: false, msg: error.message});
}
})
// 读取数据文件
ipcMain.handle('read-file', async (event, filename) => {
try {
const filePath = path.join(specifiedDirectory, filename);
return new Promise((resolve, reject) => {
if (fs.existsSync(filePath)) {
fs.readFile(filePath, "utf8", function(err, dataStr){
if(err) return reject({ok: false, msg: err.message});
resolve({ok: true, msg: JSON.parse(dataStr)});
})
} else {
resolve({ok: false, msg: "无对应文件"});
}
})
} catch (error) {
console.error('background.js读取数据文件时出错:', error);
return Promise.reject({ok: false, msg: error.message});
}
})
// 删除数据文件
ipcMain.handle('remove-file', async (event, filename) => {
try {
const filePath = path.join(specifiedDirectory, filename);
return new Promise((resolve, reject) => {
if (fs.existsSync(filePath)) {
fs.unlink(filePath, function (err) {
if(err) return reject({ok: false, msg: err.message});
resolve({ok: true, msg: "删除成功"});
})
} else {
resolve({ok: false, msg: "无对应文件"});
}
})
} catch (error) {
console.error('background.js删除数据文件时出错:', error);
return Promise.reject(false, error.message);
}
})
async function createWindow() {
const win = new BrowserWindow({
width: 1280,
height: 800,
frame: isDevelopment, // 无边框窗口
resizable: isDevelopment, // 不允许拖拽窗口大小
webPreferences: {
nodeIntegration: false, // 禁用 Node.js 集成
contextIsolation: true, // 启用上下文隔离
webSecurity: false,//允许跨域
preload: path.join(__dirname, 'preload.js')
}
})
if(!isDevelopment) win.removeMenu() // 移除窗口菜单
if (process.env.WEBPACK_DEV_SERVER_URL) {
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
win.loadURL('app://./index.html')
}
win.maximize()
}
预加载脚本
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronApi', {
/**
* 写入数据文件
* @param {*} options { data, filename } data:待写入数据。filename:数据文件名称
* @returns
*/
writeFile: async (options) => {
try {
const { data, filename } = options;
return await ipcRenderer.invoke('write-file', { data, filename });
} catch (error) {
console.error('preload.js写入数据文件时出错:', error);
return { ok: false, msg: error.message };
}
},
/**
* 读取数据文件
* @param {object} filename 数据文件名称
* @returns
*/
readFile: async (filename) => {
try {
return await ipcRenderer.invoke('read-file', filename);
} catch (error) {
console.error('preload.js读取数据文件时出错:', error);
return { ok: false, msg: error.message };
}
},
/**
* 删除数据文件
* @param {object} filename:数据文件名称
* @returns
*/
removeFile: async (filename) => {
try {
return await ipcRenderer.invoke('remove-file', filename);
} catch (error) {
console.error('preload.js删除数据文件时出错:', error);
return { ok: false, msg: error.message };
}
},
});
渲染进程
封装代码
common.js
/**
* 数据写入
* @param {object} data 待写入数据
* @param {string} filename 文件名
*/
writeF(data, filename){
const options = {
data: data,
filename: filename
};
window.electronApi.writeFile(options).then(res => {
console.log(res);
})
},
/**
* 数据读取
* @param {string} filename 文件名
*/
async readF(filename){
return await window.electronApi.readFile(filename);
},
/**
* 数据删除
* @param {string} filename 文件名
*/
removeF(filename){
window.electronApi.removeFile(filename).then(res => {
console.log(res);
return res;
})
},
调用
file.vue
//写入
this.writeF({name:'123',age:23}, 'aa.json');
//读取
this.readF('aa.json').then(res => {
console.log('res', res);
});
//删除
this.removeF('aa.json');
后文
一起进步,冲冲冲!