快速上手electron

官方文档: https://www.electronjs.org/zh/docs/latest/

搭建项目

新建文件夹并初始化项目

mkdir my-electron-app && cd my-electron-app
npm init -y

注意:新生成的package.json的author(作者)和description(描述)字段要填写补全,不然后期打包会打不了

package.json入口文件修改为main.js,修改如下:

{
   
  "name": "electron",
  "version": "1.0.0",
  "description": "这是我的第一个electron项目",
  "main": "main.js",
  "scripts": {
   
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "萧寂",
  "license": "ISC"
}

安装electron

cnpm i --save-dev electron
// 或者
npm i --save-dev electron
// 或者
yarn add --dev electron

安装过程可能会很慢,等着就行了,除非报错

package.json下面修改脚本如下,新增一个start命令

{
   
  "name": "electron",
  "version": "1.0.0",
  "description": "这是我的第一个electron项目",
  "main": "main.js",
  "scripts": {
   
    "start": "electron ."
  },
  "keywords": [],
  "author": "萧寂",
  "license": "ISC",
  "devDependencies": {
   
    "electron": "^31.2.0"
  }
}

根目录下新建main.js

console.log('electron start')

执行yarn run start

控制台如果有打印上面那句话则代表electron项目已经启动了,目前还没创建窗体,至此,项目创建准备已经结束

在主进程创建窗口并显示外部链接页面

main.js

const {
    app, BrowserWindow } = require('electron')

// 当app准备好就执行创建一个窗口
app.on('ready', () => {
   
  // 创建窗口
  let win = new BrowserWindow({
   
    x: 100,
    y: 50, //窗体坐标
    show: true, // false为不展示窗体,默认true展示,相当于将窗口隐藏了
    width: 800,
    height: 600, //长宽
    // maxHeight: 600,
    // maxWidth: 1000, //最大宽高
    minHeight: 200,
    minWidth: 300, //最小宽高
    resizable: true, //是否允许缩放
    title: "萧寂", //标题(加上这个属性,在页面中就不要有title标签了)
    // icon: "./icon.png", //设置icon图标
    // frame: false, //只保留主体部分,不保留其他的选项卡窗口了,隐藏菜单栏
    // transparent: true, //将窗体完全透明化
    autoHideMenuBar: true, //只保留标题,不保留其他的选项卡部分,也是隐藏菜单栏意思
    alwaysOnTop:true, // 将窗口置顶
  })
  win.loadURL('https://xiaojiblog.netlify.app/') // 打开外部链接
})

运行yarn run start

效果图

在这里插入图片描述
支持放大全屏,也可以在上面参数里面把最大宽度高度限制放开,不设置的话就默认可以全屏

更多配置项参考:https://www.electronjs.org/zh/docs/latest/api/base-window#class-basewindow

在主进程加载并显示本地页面

根目录下创建/pages/index.html和/pages/index.css

/pages/index.html内容如下

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./index.css">
</head>

<body>
  <h1>第一个本地electron页面</h1>
</body>

</html>

/pages/index.css内容如下

h1{
   
  background-color: gray;
  color: orange;
}

修改主进程代码main.js如下

const {
    app, BrowserWindow } = require('electron')

// 当app准备好就执行创建一个窗口
app.on('ready', () => {
   
  // 创建窗口(下面的配置在上面讲过了,这里就删掉了,只留下三个)
  let win = new BrowserWindow({
   
    width: 800,
    height: 600, //长宽
    autoHideMenuBar: true, //只保留标题,不保留其他的选项卡部分,也是隐藏菜单栏意思
  })

  win.on('close', () => {
   
    // 从性能考虑,应该释放窗体这个变量,删除窗体引用
    win = null
  })
	
  win.loadFile('./pages/index.html') // loadFile就是加载本地页面的,loadURL加载的是在线链接
})

运行yarn run start

效果图如下:

在这里插入图片描述

electron生命周期事件

ready:app初始化完成  //重要
dom-ready:一个窗口中的文本加载完成  //重要
did-finsh-load:导航完成时触发   //重要
window-all-closed:所有窗口都被关闭时触发  //重要
before-quit:在关闭窗口之前触发
will-quit:在窗口关闭并且应用退出时触发
quit:当所有窗口被关闭时触发
close:当窗口关闭时触发,此时应删除窗口引用

main.js代码

const {
    app, BrowserWindow } = require("electron")
const createWindow = () => {
   
  // 创建窗口
  let win = new BrowserWindow({
   
    width: 800,
    height: 600,
  })
  //当前窗口显示的页面
  win.loadFile("index.html")

  // 这个webContents对象可以控制dom元素加载事件
  win.webContents.on('did-finish-load', () => {
   
    console.log('3333->did-finish-load')
  })
  win.webContents.on('dom-ready', () => {
   
    console.log('2222->dom-ready')
  })
  // 窗口关闭
  win.on('close', () => {
   
    console.log('8888->close')
    // 从性能考虑,应该释放窗体这个变量,删除窗体引用
    win = null
  })
}

// 生命周期
// 通过on监听事件
app.on('ready', () => {
   
  console.log("1111->ready")
  createWindow()
})

app.on("window-all-closed", () => {
   
  // 如果监听了window-all-closed这个事件,需要在事件里面主动退出应用,没有监听事件的话默认会直接退出应用
  // 但如果监听了此事件,但没有退出操作的话,后续的567生命周期也不会执行
  console.log("4444->window-all-closed")
  //退出应用
  app.quit()
})

app.on("before-quit", () => {
   
  console.log("5555->before-quit")
})

app.on("will-quit", () => {
   
  console.log("6666->will-quit")
})

app.on("quit", () => {
   
  console.log("7777->quit")
})

从打开窗体到关闭窗体打印结果如下

在这里插入图片描述

打开控制台调试工具

在当前窗口按下ctrl+shift+i

效果图:
在这里插入图片描述

刷新页面

按下ctrl+r

启动项目遇到的两个警告

1.自动填充问题,在vscode终端打印的警告内容,官方未做处理,electron开发者回复不影响开发可以先忽略,警告内容如下:

[892:0714/014647.854:ERROR:CONSOLE(1)] "Request Autofill.enable failed. {"code":-32601,"message":"'Autofill.enable' wasn't found"}", source: devtools://devtools/bundled/core/protocol_client/protocol_client.js (1)
[892:0714/014647.854:ERROR:CONSOLE(1)] "Request Autofill.setAddresses failed. {"code":-32601,"message":"'Autofill.setAddresses' wasn't found"}", source: devtools://devtools/bundled/core/protocol_client/protocol_client.js (1)

2.在窗口的ctrl+shift+i的控制台,会有个warning的报错,是关于(Insecure Content-Security-Policy)的,是内容安全的警告,解决方式如下:

在html页面上新增一个meta标签,内容如下

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;">

然后再次启动项目就会发现警告没了

完善窗口关闭行为

在Windows和Linux上,关闭所有窗口通常会完全退出一个应用程序。

但是在mac上,关闭所有窗口并不会完全退出程序,因此这里需要对mac电脑进行一个判断

官方介绍: https://www.electronjs.org/zh/docs/latest/tutorial/quick-start#%E7%AE%A1%E7%90%86%E7%AA%97%E5%8F%A3%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F

在主进程加上下面的事件和判断,修改main.js如下:

const {
    app, BrowserWindow } = require('electron')

// 创建窗口
function createWindow () {
   
  // 创建窗口
  let win = new BrowserWindow({
   
    width: 800,
    height: 600, //长宽
    autoHideMenuBar: true, //只保留标题,不保留其他的选项卡部分,也是隐藏菜单栏意思
  })

  win.on('close', () => {
   
    // 从性能考虑,应该释放窗体这个变量,删除窗体引用
    win = null
  })

  win.on('close', () => {
   
    // 从性能考虑,应该释放窗体这个变量,删除窗体引用
    win = null
  })
	
  win.loadFile('./pages/index.html')
}

// 当app准备好就执行创建一个窗口
app.on('ready', () => {
   
  createWindow()

  // 监听应用被激活
  app.on('activate', () => {
   
    // 当应用激活后,窗口数量为0时,重新创建一个窗口(mac使用,在windows和Linux窗口为0直接退出了)
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 监听所有窗口都被关闭事件
app.on('window-all-closed', () => {
   
  // 不是mac系统就执行退出
  if (process.platform !== 'darwin') app.quit()
})

配置热更新自动重启

安装插件

yarn add nodemon -D

修改package.json下面的script节点的start命令如下:

"start": "nodemon --exec electron ."

运行yarn run start

然后会发现.html后缀的文件内容更换了并不会自动重启项目,只有main.js主进程代码更换了才重启,为了解决这个问题,继续往下看

根目录下新建nodemon.json文件,内容如下:

{
   
  "ignore": [ // 忽略那些文件夹
    "node_modules",
    "dist"
  ],
  "restartable": "r", // 短命令,当文件没更改,在终端输入字母r可以自动重启
  "watch": ["*.*"], // 监视所有文件
  "ext": "js,json,html,css,vue" // 包含的文件名后缀
}

运行yarn run start再次重启项目就会发现一切正常,都可以实现自动刷新了

主进程与渲染进程进行通信(下面两种方式选其一即可)

简单来说就是渲染进程浏览器环境不能调用主进程的nodejs的相关api和方法,进行通信后就可以了,下面是两种方式,
第一种是:将渲染进程设置为可以访问nodejs方法,这时候渲染进程拥有了访问window环境和nodejs环境的方法和api调用
第二种是:使用预加载脚本,当有需求要操作nodejs的api调用时,渲染进程调用预加载脚本的对应方法,向主进程发起通信事件,主进程接收到对应的事件后就会执行操作

一:在渲染进程直接使用nodejs的所有api调用,本人常用方式(简单)

后面所有的案例都是使用这个方式在渲染进程里面做操作

需求: 用户输入文字后获取输入框内容并写入本地hello.txt文件内,点击第二个按钮可以将写入的文件内容信息弹出来

修改/pages/index.html内容如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="Content-Security-Policy"
    content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;">
  <title>Document</title>
  <link rel="stylesheet" href="./index.css">
</head>

<body>
  <h1>第haha本地electron页面</h1>
  <input type="text" id="input">
  <br>
  <button id="btn1">向D盘写入文件hello.txt</button>
  <br>
  <button id="btn2">读取D盘hello.txt文件</button>
  <script src="./render.js"></script>
</body>

</html>

修改main.js如下

const {
    app, BrowserWindow } = require('electron')
const path = require('path')
// 创建窗口
function createWindow () {
   
  // 创建窗口
  let win = new BrowserWindow({
   
    width: 800,
    height: 600, //长宽
    autoHideMenuBar: true, //只保留标题,不保留其他的选项卡部分,也是隐藏菜单栏意思
    webPreferences: {
   
      nodeIntegration: true,  // 配置这三个选项就可以实现在渲染进程使用nodejs的api调用
      contextIsolation: false,
      enableRemoteModule: true
    }
  })

  win.on('close', () => {
   
    win = null
  })
	
  win.loadFile('./pages/index.html')
}

// 当app准备好就执行创建一个窗口
app.on('ready', () => {
   
  createWindow()
})

渲染进程render.js内容改为如下

const fs = require('fs')
const btn = document.getElementById('btn1')
const btn2 = document.getElementById('btn2')
const input = document.getElementById('input')
btn.addEventListener('click', () => {
   
  // 向D盘写入文件
  fs.writeFileSync('D:/hello.txt', input.value) // 直接调用nodejs写入文件的方法
})
btn2.addEventListener('click', async () 
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萧寂173

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值