项目源码
https://github.com/electron-in-action/firesale/tree/chapter-4
目标
- eletron dialog模块
- 主进程与渲染进程通信
- electron remote模块
- webContents渲染进程发送消息
- electron ipcRenderer模块
代码
main.js
const { app, BrowserWindow, dialog } = require('electron');
...
const getFileFromUser = exports.getFileFromUser = () => {
//2.x
/* const files = dialog.showOpenDialog(mainWindow, {
properties: ['openFile'],
filters: [
{ name: 'Text Files', extensions: ['txt'] },
{ name: 'Markdown Files', extensions: ['md', 'markdown'] }
]
}
});
if (files && files[0]) {
openFile(files[0]);
} // A
*/
/*
//5.x
dialog.showOpenDialog({
properties: ['openFile']
, filters: [
{ name: 'Markdown Files', extensions: ['md', 'markdown'] },
{ name: 'Text Files', extensions: ['txt'] }
]
}, (files) => {
if (files) {
openFile(files[0]);
}
})
*/
//9.x
dialog.showOpenDialog({
properties: ['openFile']
, filters: [
{ name: 'Markdown Files', extensions: ['md', 'markdown'] },
{ name: 'Text Files', extensions: ['txt'] }
]
}).then(result => {
console.log(result.canceled);
console.log(result.filePaths);
if (result.filePaths) {
openFile(result.filePaths[0]);
}
}).catch(err => {
console.log(err)
})
};
const openFile = (file) => {
const content = fs.readFileSync(file).toString();
mainWindow.webContents.send('file-opened', file, content); // B
};
renderer.js
const { remote, ipcRenderer } = require('electron');
const mainProcess = remote.require('./main.js');
...
openFileButton.addEventListener('click', () => {
mainProcess.getFileFromUser();
});
ipcRenderer.on('file-opened', (event, file, content) => {
markdownView.value = content;
renderMarkdownToHtml(content);
});
代码解析
eletron dialog模块
dialog.showOpenDialog
各个版本的写法不相同, 9.x 使用
//9.x
dialog.showOpenDialog({
properties: ['openFile']
, filters: [
{ name: 'Markdown Files', extensions: ['md', 'markdown'] },
{ name: 'Text Files', extensions: ['txt'] }
]
}).then(result => {
console.log(result.canceled);
console.log(result.filePaths);
if (result.filePaths) {
openFile(result.filePaths[0]);
}
}).catch(err => {
console.log(err)
})
remote模块
remote模块从渲染进程向主进程发起跨进程通信的方法,
remote模块仅能用于渲染进程
是主进程的一个镜像
使用:
- 主进程( main.js)
在主进程中,使用exports.xxx
导出属性和方法
const getFileFromUser = exports.getFileFromUser = () => {
...
}
- 渲染进程(renderer.js)
const mainProcess = remote.require('./main.js'); 引入 主进程 返回主进程的一个代理对象
这就可以使用remote.require
引入主进程导出(exports.xxx
)的功能
const { remote } = require('electron'); //引入 remote
const mainProcess = remote.require('./main.js'); // 引入 主进程
...
mainProcess.getFileFromUser(); //使用主进程自定义的内容
...
IPC 模块
- 主进程
- 使用
mainWindow.webContents.send()
发送消息
- 使用
mainWindow.webContents.send('file-opened', file, content);
- 使用
ipcMain
接收、发送消息
参看: https://www.cnblogs.com/easy5weikai/p/13080974.html
let { ipcMain} = require('electron');
...
app.on('ready', () => {
...
ipcMain.on("msg_renderer_to_main", (event, param1, param2) => {
//主进程向渲染进程发送消息:方式一
event.sender.send("msg_main_to_renderer_bysend", { "arg1": "send" }, "msg from main by send!");
//主进程向渲染进程发送消息:方式二
event.reply("msg_main_to_renderer_byreply", { "reply-arg1": "reply" }, "msg from main by reply!");
//主进程向渲染进程发送消息:方式三(等同于 mainWindow.webContents.send)
mainWindow.send("msg_main_to_renderer_byWindow", { "Window-arg1": "reply" }, "msg from main by Window!");
})
});
- 渲染进程
引入ipcRenderer
模块,然后ipcRenderer.on()
接收信息
const { ipcRenderer } = require('electron'); 引入ipcRenderer
...
ipcRenderer.on('file-opened', (event, file, content) => {
...
});
CommonJs模块系统
Node模块中,会显式地声明要导出的功能
每一Node模块都有一个内置的exports
,最开始其不包含任何属性
当已入一个模块时,会引入该模块的添加到export
对象的所有东西。
common.js
exports.addTwo = (a)=>{
return a + 2;
}
xxx.js
const common = require('./common.js');
common.addTwo(4);//返回6