整体效果
整体目录结构
主窗口开发
index.js
const electron = require('electron');
const {app, BrowserWindow, Menu} = electron;
const path = require('path');
const url = require('url');
let win = null;
app.on('ready', () => {
win = new BrowserWindow({
width: 800,
height: 600
});
// win.loadURL("https://baidu.com")
win.loadURL(url.format({
pathname: path.resolve(__dirname, './html/main.html'),
protocol: 'file:',
slashes: true
}));
// 定义菜单
const mainMenu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(mainMenu);
});
const menuTemplate = [
// 文件菜单项
{
label: '文件',
submenu: [
{
label: '新增信息',
},
{
label: '清空信息',
},
{
label: '退出',
accelerator: process.platform == 'darwin' ? 'Command+Q' : 'Ctrl+Q',
click: ()=> {
app.quit();
}
}
]
},
// 开发者工具菜单项
{
label: '开发者工具',
submenu: [
{
label: '打开/关闭',
click: (item, focusedWindow)=> {
focusedWindow.toggleDevTools()
}
},
{
label: '刷新一下',
role: 'reload',
accelerator: process.platform == 'darwin' ? 'Command+F5' : 'Ctrl+F5'
}
]
}
];
此时效果
安装cross-env模块包,帮助我们设置process环境变量
npm install cross-env --save-dev
线上及开发环境配置
package.json
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "cross-env NODE_ENV=delevopment electron .",
"start-prod": "cross-env NODE_ENV=production electron ."
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"cross-env": "^7.0.3",
"electron": "^21.0.0",
"electron-packager": "^16.0.0"
}
}
npm start // run可忽略
npm run start-prod // run不可忽略
index.js使用process判断当前环境
const checkEnv = () => {
let env = process.env.NODE_ENV;
let devConfig =
// 开发者工具菜单项
{
label: '开发者工具',
submenu: [
{
label: '打开/关闭',
click: (item, focusedWindow)=> {
focusedWindow.toggleDevTools()
}
},
{
label: '刷新一下',
role: 'reload',
accelerator: process.platform == 'darwin' ? 'Command+F5' : 'Ctrl+F5'
}
]
};
// 开发环境
if (env != 'production') {
menuTemplate.push(devConfig)
}
};
子窗口开发并打开
add.html
<!DOCTYPE html>
<html>
<head>
<title>新增信息</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="./css/basic.css" />
</head>
<body>
<section class="form-box">
<form>
<label for="info">请输入信息名称</label>
<input type="text" name="info" id="info" placeholder="请输入信息名称" autofocus />
<button type="submit" class="btn btn-add">添加</button>
</form>
</section>
<style type="text/css">
.form-box{width:80%;margin:0 auto;margin-top:5px;}
.btn-add{width:100%;margin-top:2px;}
</style>
</body>
</html>
子窗口通信 add.html
const electron = require('electron');
const { ipcRenderer } = electron;
const form = document.querySelector('form');
// submit 事件
form.addEventListener('submit',(ev) => {
ev.preventDefault(); // 阻止刷新
let val = document.querySelector('#info').value;
// console.log(val);
// 发送传递信息
ipcRenderer.send("info:add", val);
});
index.js监听事件信息传递
index.js
// 事件监听: 监听事件信息的传递
const eventListen = () => {
// 监听新增窗口传递过来的 信息项
ipcMain.on('info:add',(e, val) => {
win.webContents.send('info:add', val);
addWin.close();
})
};
eventListen();
主窗口通信
main.html
const electron = require('electron');
const { ipcRenderer } = electron;
const ul = document.querySelector('#wrap');
const spaceSection = document.querySelector('.space-section');
// 接收 新增信息窗口传递过来的数据
ipcRenderer.on('info:add',(e, val) => {
const li = document.createElement('li');
ul.className = 'collection';
li.className = "collection-item";
li.innerHTML = val+' <i class="close-btn">×</i>';
ul.append(li);
spaceSection.style.display = 'none';
});
package.json整体代码
{
"name": "electron-infolist",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "cross-env NODE_ENV=development electron .",
"start-prod": "cross-env NODE_ENV=production electron .",
"build-win": "electron-packager . info-list-app --out=dist --overwrite --platform=win32 --arch=x64 --prune=true --icon=icon/win/icon.ico",
"build-linux": "electron-packager . info-list-app --out=dist --overwrite --platform=linux --arch=x64 --prune=true --icon=icon/linux/icon.png",
"build-mac": "electron-packager . info-list-app --out=dist --overwrite --platform=darwin --arch=x64 --prune=true --icon=icon/mac/icon.icns"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"cross-env": "^6.0.0",
"electron": "^6.0.10",
"electron-packager": "^13.1.1"
}
}
index.js整体代码
const electron = require('electron');
const { app, BrowserWindow, Menu, ipcMain } = electron;
const path = require('path');
const url = require('url');
let win = null;
let addWin = null;
app.on('ready', () => {
win = new BrowserWindow({
width: 800, height: 600, webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
win.loadURL(url.format({
pathname: path.resolve(__dirname,'./html/main.html'),
protocol: 'file:',
slashes: true
}));
// 定义菜单
const mainMenu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(mainMenu);
// 点击主窗口的关闭按钮
win.on('closed', () => {
app.quit();
});
});
// 顶部菜单 模板
const menuTemplate = [
// 文件菜单项
{
// 顶部菜单的名称
label: '文件',
// 顶部菜单下面的子菜单列表
submenu: [
{
label: '新增信息',
click: () => {
createAddWindow()
}
},
{
label: '清空信息',
click: () => {
win.webContents.send('info:clear');
}
},
{ label: '退出',
accelerator: process.platform == 'darwin' ? 'Command+D' : 'Ctrl+D',
click: () => {
// 退出
app.quit();
}
}
]
}
];
// 创建一个新的窗口
const createAddWindow = () => {
addWin = new BrowserWindow({
width: 600, height: 300, webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
addWin.loadURL(url.format({
pathname: path.resolve(__dirname,'./html/add.html'),
protocol: 'file:',
slashes: true
}));
};
// 检测当前环境
const checkEnv = () => {
if(process.env.NODE_ENV == undefined){
process.env.NODE_ENV = 'production';
}
let env = process.env.NODE_ENV;
// 开发者工具菜单项
let devConfig = {
label: '开发者工具',
submenu: [
{
label: '打开/关闭',
accelerator: process.platform == 'darwin' ? 'Command+I' : 'Ctrl+I',
click: (item, focusedWindow) => {
focusedWindow.toggleDevTools();
}
},
{ label: '刷新一下',
role: 'reload',
accelerator: process.platform == 'darwin' ? 'Command+F5' : 'Ctrl+F5'
}
]
};
console.log(env);
// 开发的环境
if(env !== 'production'){
menuTemplate.push(devConfig);
}
};
checkEnv();
// 事件监听: 监听事件信息的传递
const eventListen = () => {
// 监听新增窗口传递过来的 信息项
ipcMain.on('info:add',(e, val) => {
win.webContents.send('info:add', val);
addWin.close();
})
};
eventListen();
main.html整体代码
<!DOCTYPE html>
<html>
<head>
<title>信息列表</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="./css/basic.css" />
</head>
<body>
<!-- 标题面板 -->
<nav>
<div class="nav-wrapper">
<a href="#" class="brand-logo">信息列表</a>
</div>
</nav>
<!-- 信息列表 -->
<ul id="wrap">
<!-- <li class="collection-item"> 信息列表项001 <i class="close-btn">×</i> </li>
<li class="collection-item"> 信息列表项002 <i class="close-btn">×</i> </li>
<li class="collection-item"> 信息列表项003 <i class="close-btn">×</i> </li>
<li class="collection-item"> 信息列表项004 <i class="close-btn">×</i> </li>
<li class="collection-item"> 信息列表项005 <i class="close-btn">×</i> </li> -->
</ul>
<!-- 提示 -->
<h3 class="space-section"> 暂无信息,请添加信息 </h3>
<style type="text/css">
.space-section{ text-align: center;color:#666;font-size:18px;height:100px;line-height: 100px; }
ul li {position: relative;}
.close-btn{position: absolute;width:30px;height:30px;text-align: center;cursor: pointer;font-size:25px;right: 10px;top: 7px;color:#ccc;}
.close-btn:hover{color:#333;}
</style>
<script>
const electron = require('electron');
const { ipcRenderer } = electron;
const ul = document.querySelector('#wrap');
const spaceSection = document.querySelector('.space-section');
// 接收 新增信息窗口传递过来的数据
ipcRenderer.on('info:add',(e, val) => {
const li = document.createElement('li');
ul.className = 'collection';
li.className = "collection-item";
li.innerHTML = val+' <i class="close-btn">×</i>';
ul.append(li);
spaceSection.style.display = 'none';
domListener();
});
// 接收 清空信息的按钮事件传递
ipcRenderer.on('info:clear',(e) => {
ul.className = '';
ul.innerHTML = '';
spaceSection.style.display = 'block';
});
// dom 监听
function domListener(){
document.querySelectorAll('.close-btn').forEach(el => {
el.addEventListener('click', function(ev){
this.parentNode.remove();
// 判断列表是否为空
if(ul.children.length == 0){
ul.className = ''
// ul.classList.remove('collection')
spaceSection.style.display = 'block';
}
});
})
}
domListener();
</script>
</body>
</html>
add.html整体代码
<!DOCTYPE html>
<html>
<head>
<title>新增信息</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="./css/basic.css" />
</head>
<body>
<section class="form-box">
<form>
<label for="info">请输入信息名称</label>
<input type="text" name="info" id="info" placeholder="请输入信息名称" autofocus />
<button type="submit" class="btn btn-add">添加</button>
</form>
</section>
<style type="text/css">
.form-box{width:80%;margin:0 auto;margin-top:5px;}
.btn-add{width:100%;margin-top:2px;}
</style>
<script>
const electron = require('electron');
const { ipcRenderer } = electron;
const form = document.querySelector('form');
// submit 事件
form.addEventListener('submit',(ev) => {
ev.preventDefault(); // 阻止刷新
let val = document.querySelector('#info').value;
// console.log(val);
// 发送传递信息
ipcRenderer.send("info:add", val);
});
</script>
</body>
</html>
打包