二、前提条件
1、安装 node
node -v
mpm -v
安装完成后就可以安装electron了
2、创建基本应用程序
my-electron-app/
├── package.json // npm init 生成应用程序配置文件
├── main.js // 手动创建应用程序出口文件(主线程)
└── index.html
3、安装
npm i -save-dev electron // 项目内安装
npm i -g electron // 全局
4、主进程文件
const { app, BrowserWindow } = require('electron') // 引入electron
function createWindow () {
// 实例化一个BrowserWindow,创建应用程序第一个窗口
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true, // 是否需要在渲染进程中使用 nodejs
}
})
win.loadFile('index.html') // 加载文件,将页面记载到窗口中
}
// whenReady 当electron 初始化完成时创建窗口
app.whenReady().then(createWindow)
// 监听窗口关闭事件,所有窗口关闭时退出应用,macOs 则不退出,切到后台
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
// mac os 中点击dock 中的应用图标的时候重新创建窗口
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
5、运行程序
npm start
6、app 常用事件触发场景
ready 当electron 完成时被触发
window-all-closed 所有窗口被关闭触发
before-quit 在开始关闭窗口之前触发
will-quit 咋所有窗口已经关闭并且应用将要退出时
quit 在应用程序退出时触发
// 实例
app.on('ready',()=>{
// ... 具体实现
}))
7、webview 标签
在使用webview 之前,需要在webPreferences 中配置 webviewTag:true 即可使用。
// 主进程
const win = new BrowserWindow({
width:500,
height:300,
webPreferences:true,
nodeIntegration:true, // 开启后可在webview加载的页面可以使用node
})
// 页面
<webview id="view" src="https://www.baidu.com" ></webview>
8、BrowserWindow
创建和控制浏览器窗口
// 主进程中
const { BrowserWindow } = require('electron')
// 渲染进程中
const { BrowserWindow } = require('electron').remote
// 创建窗口
const win = new BrowserWindow({
width:500,
height:300,
show:false, // 是否显示此窗口
frame:true // 加载边框的窗口欧
})
const path = require('path')
// win 加载方法
win.loadURL('https://www.baidu.com') // 加载网站地址
win.loadFile(path.join(__dirname,'index.html')) // 加载文件地址
优雅显示窗口 避免用户看到未加载完成的页面,方法有两种
1.使用 ready-to-show 事件 (常用)
win.once('ready-to-show',()=>{
win.show()
})
2.设置背景
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ backgroundColor: '#2e2c29' })
win.loadURL('https://github.com')
三、父子窗口、模态窗口、页面可见性
1.可以通过 parent 选项指定父级窗口,指定后子窗口将总是显示在父窗口顶部。
const { BrowserWindow } = require('electron')
const top = new BrowserWindow()
const child = new BrowserWindow({
parent: top,
modal:true, // 开启模态
show:false
})
child.show()
top.show()
父子窗口通信 window.opener.postMessage( data , origin )
// 子向子通信
子:
window.opener.postMessage('...数据...','*')
父:
window.addEventListener("message",(data)=>{
// console.log(data)
})
// 父向子通信
2.页面可见性
① 在所有平台上,可见性状态与窗口是否隐藏/最小化相关。
② macOs 上,可见性状态还会跟踪窗口的遮挡状态。如果窗口被另一个窗口遮挡,则此窗口的可见性状态为 hidden;使用 win.hide() 使窗口最小化或者隐藏。
四、主进程渲染进程通信
ipcMain
接收渲染进程消息 ipcMain.on( key , callback )
发送给渲染进程消息 win.webContents.send( key , msg )
// 接收
ipcMain.on("asynchronous-message",(event,msg)=>{
// 建议使用异步发送,避免阻塞进程
event.reply("reply-to-renderer",'我也给你发一条消息,礼尚往来嘛!') // 异步发送时
event.returnValue'我也给你发一条消息,礼尚往来嘛!'// 同步步发送时
console.log(msg)
})
// 发送
let win = new BrowserWindow()
win.webContents.send('send-to-renderer','来自主线程的问候')
ipcRenderer
接受主进程消息 ipcRenderer.on( key , callback )
发送给主进程消息 ipcRenderer.send( key ,msg )
// 发送
ipcRenderer.send("asynchronous-message", 'BooM')
ipcRenderer.sendSync("synchronous-message", 'sync BooM')
// 接收
ipcRenderer.on("reply-renderer-msg", (event, msg) => {
console.log(msg);
})
五、原生应用菜单
// 主进程
const {Menu,MenuItem} from 'electron'
// 静态方法
const template = [
{
label:'菜单一',
click:()=>{
console.log("点击菜单一")
}
},
{
type:'separator'// 菜单分割线
},
{
label:'菜单二'
},
{
type:'separator'// 菜单分割线
}
{
label:'撤销',
type:'undo'
},
{
type:'separator'// 菜单分割线
}
{
label:'保留',
type:'redo'
}
]
const menu = Menu.buildFromTemplate(template) // 创建菜单
Menu.setApplicationMenu(menu) // 设置菜单
// 弹出菜单
menu.popup()
menu.append(new MenuItem({label:'新增菜单'}))
menu.insert(new MenuItem({label:'插入菜单'}))
六、网络 (不建议使用 )
net 是客户端发送请求客户端的Api, 他使用Chromiun的原生网络库来代替Node实现,可实现网络代理。
const { app } = require('electron')
app.whenReady().then(() => {
const { net } = require('electron')
const request = net.request('https://www.baidu.com') // 创建并返回request对象
request.on('response', (response) => { // 监听请求响应
console.log(`STATUS: ${response.statusCode}`)
console.log(`HEADERS: ${JSON.stringify(response.headers)}`)
response.on('data', (chunk) => { // 监听响应数据
console.log(`BODY: ${chunk}`)
})
response.on('end', () => { // 监听请求终止
console.log('No more data in response.')
})
})
request.end() // 通知后台数据发送完毕,请求中断请求
})
注:建议使用axios/fetch … 等第三方网络库。都可与 electron 高度集成。
七、Vue / React 高度集成
注:个人原因这里解释与 vue 集成
// vue
1.安装脚手架
npm install -g -vue-cli
2.创建工程
vue init simulatedgreg/electron-vue electron-vue-start
// 如果长时间下载仍未成功,可使用以下操作来创建项目
// 将simulatedgreg/electron-vue模板下载至本地,在本地创建项目
cmd 运行
git clone https://gitee.com/mirrors/electron-vue.git
本地创建项目
cmd 运行
vue init D:\electron_pro\electron-vue electron-vue-start
接下来的流程同上
3.安装依赖与启动
cd elemctron-vue-start
npm run dev
或
yarn dev
// 目录
// vue
1.安装脚手架
npm install -g -vue-cli
2.创建工程
vue init simulatedgreg/electron-vue electron-vue-start
// 如果长时间下载仍未成功,可使用以下操作来创建项目
// 将simulatedgreg/electron-vue模板下载至本地,在本地创建项目
cmd 运行
git clone https://gitee.com/mirrors/electron-vue.git
本地创建项目
cmd 运行
vue init D:\electron_pro\electron-vue electron-vue-start
接下来的流程同上
3.安装依赖与启动
cd elemctron-vue-start
npm run dev
或
yarn dev
// 目录
│
├── README.md <= 项目介绍
├── app <= 开发目录
│ ├── dist <= 编译打包
│ ├── icons <= 相关图标
│ ├── src <= 项目源代码
│ │ ├── main <= electron主进程
│ │ │ ├── application.js
│ │ │ ├── index.dev.js
│ │ │ ├── index.js
│ │ ├── renderer <= electron渲染进程
│ │ │ ├── App.vue <= Vue 根组件
│ │ │ ├── main.js <= Vue 入口
│ │ │ ├── assets <= 静态资源
│ │ │ ├── common <= 公共配置
│ │ │ ├── config <= 项目配置
│ │ │ ├── extend <= Vue 扩展相关
│ │ │ ├── router <= Vue 路由相关
│ │ │ ├── store <= Vuex
│ │ │ ├── views <= 视图层
│ ├── index.ejs <= 模板文件
│ ├── package.json <= 相关依赖
├── build <= 打包桌面应用相关
│ ├── Gruntfile.js <= 构建脚本
│ ├── package.json <= 相关依赖
├── tasks <= electron-packeger打包
│ ├── release.js
│ ├── runner.js
├── test <= 测试文件夹
│ ├── e2e
│ ├── unit
│ ├── .eslin
八、应用打包
npm run build // 应用打包
npm run build:web // web打包
终于介绍完了,下面我们休息一下吧 ~,喜欢的留下你的小脚印。