Electron快速入门

news2024/10/7 9:20:33

目录

前言

一、安装需知

二、安装electron

三、开始

3.1 修改package.json文件

3.2 创建main.js文件

3.3 启动预览窗口

3.4 显示内容

四、 热加载

五、主进程和渲染进程概念介绍

六、自定义原生菜单

6.1 自定义菜单

6.2 给菜单添加点击事件

6.3 抽离菜单定义

6.4 无边框菜单

6.4.1 为无边框菜单添加新建窗口点击事件

6.4.2 小总结

6.4.2 点击打开网页

七、打开对话框读取文件


前言

Electron是由GitHub众多开发者开发的一个开源项目,能够使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。

当然了,它也可以与vue和react相结合。前端的小伙伴们,学习它应该很快,是很容易上手的一门技术。

文档编写不易,还请各位耐心观看。另外本人能力有限,如有不足之处,还请不吝批评指正!

一、安装需知

需要提前安装好Nodejs,因为Electron依赖于Nodejs。

注意二者有版本要求,比如Electron的v25.0.1版本就要求nodejs必须大于等于18.15.0版本。

所以安装之前建议去Electron的官网查看以下对应的版本。附上地址:Electron Releases

二、安装electron

个人推荐版本:

Node:v16.13.2        Electron:v18.1.0

初始化项目

新建一个文件夹,在文件夹内初始化项目

npm init

安装electron

注意安装时指定版本,否则就是安装的最新版本。一旦安装最新版本,倘若你们nodejs不是最新的,就有可能导致无法安装,提示让你下载更高版本的nodejs。

npm install electron@v18.1.0 --save-dev

检查是否安装成功

安装完成后,我们可以通过如下命令检验版本号来判断是否安装成功

npx electron -v

或者我们可以直接进入在根路径下执行如下命令打开程序,如果弹出应用程序,说明安装成功了。

./node_modules/.bin/electron

 

三、开始

上面出现的这个应用程序界面是electron内置的一个demo样例。

下面我们就正式开发一个属于自己的界面了。

3.1 修改package.json文件

我们项目初始化完成后,默认会生成一个package.json的文件。

我们需要在scripts对象中追加一个执行命令:

"scripts": {
    "start": "electron ."
  }

当然了,执行命令叫什么自己取都行,但是实际要执行的必须是electron .

其次,我们发现"main": "index.js",但是,我们并没有这个index.js,因此需要自己在根路径下新建该文件。为了符合electron的习惯,我们习惯上将index.js命名为main.js。它就是我们主程序的入口。

所以,修改后的package.json文件如下:

{
  "name": "my-electron-app",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "electron": "electron ."
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^18.1.0"
  }
}

3.2 创建main.js文件

main.js作为程序的入口,我们应该怎么写呢?

直接看下面的代码,相关说明我都注释标注了。

// 导入electron对象
// app 控制应用程序的事件生命周期。
// BrowserWindow 创建并控制浏览器窗口。
const { app,BrowserWindow } = require('electron')

// 控制ready事件
// ready事件是:当 Electron 完成初始化时,发出一次。
app.on('ready',()=>{
  // 新建窗口
  new BrowserWindow({
    width: 800,
    height: 600
  })
})

3.3 启动预览窗口

下面,我们执行启动命令查看一下:

npm run electron

 ok,窗口成功创建出来了,我们接下来就是让他显示内容了。

3.4 显示内容

我们创建窗口之后,就可以获得这个窗口的返回对象。 

通过这个返回对象,我们可以让它加载一个HTML页面,这就是electron显示内容的方式了。

// 导入electron对象
// app 控制应用程序的事件生命周期。
// BrowserWindow 创建并控制浏览器窗口。
const { app,BrowserWindow } = require('electron')

// 控制ready事件
// ready事件是:当 Electron 完成初始化时,发出一次。
app.on('ready',()=>{
  // 新建窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600
  });
  // 让主窗口加载文件 html文件
  mainWindow.loadFile('./src/index.html');
})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>欢迎来到electron</h1>
</body>
</html>

重新执行npm run electron启动,发现就成功的读取到了我们编写的index.html页面了。 

四、 热加载

通过上面的案例我们发现,每次编写完代码都需要重新运行。这样就比较麻烦了,有没有办法让我们代码修改完成就直接能看到效果了?

这就是热加载功能。

安装十分简单:

npm install --save-dev electron-reloader

使用方法只需要在main.js的入口文件中引入即可:

// 开启热加载
const reloader = require('electron-reloader')
reloader(module)

五、主进程和渲染进程概念介绍

Electron 运行 package.jsonmain 脚本的进程被称为主进程。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。

由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它的叫渲染进程的进程中。也就是说每个页面都是渲染进程。

在普通的浏览器中,web页面无法访问操作系统的原生资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。

ctrl+shift+i打开渲染进程调试

演示快捷键

六、自定义原生菜单

6.1 自定义菜单

electron默认为我们提供了菜单栏,如上所示。

如果我们不想使用默认的原生菜单,自定义也是可以的。

这需要我们先引入electron的menu菜单对象。

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

然后我们自定义需要先配置模板,再通过模板创建出新的菜单对象,最后将菜单对象放到我们的Menu菜单对象中。

完整的代码为:

// 导入electron对象
// app 控制应用程序的事件生命周期。
// BrowserWindow 创建并控制浏览器窗口。
// Menu 创建原生应用菜单和上下文菜单。
const { app,BrowserWindow,Menu} = require('electron')

// 开启热加载
const reloader = require('electron-reloader')
reloader(module)


// 控制ready事件
// ready事件是:当 Electron 完成初始化时,发出一次。
app.on('ready',()=>{
  // 新建窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600
  });
  // 让主窗口加载文件 html文件
  mainWindow.loadFile('./src/index.html');

  // 配置模板
  const template = [
    {
      label: '文件'
    },
    {
      label: '编辑'
    },
    {
      label: '关于我们'
    }
  ]

  // 菜单对象构建该模板,生成菜单对象
  const menu = Menu.buildFromTemplate(template);
  // 设置我们构建好的菜单
  Menu.setApplicationMenu(menu);
})

ok,我们的菜单栏就彻底改变了。 

至于为什么模板中的键值为label,这个是官网要求的具体可查询相关api。Menu | Electron

ok,我们可以参考api丰富一下菜单,这里演示为文件菜单设置一些子菜单。

6.2 给菜单添加点击事件

接下来,我们实现一个功能,就是点击新建窗口的时候,让它弹出一个新的窗口。

实现起来也很容器,template中提供有click()方法来完成。

6.3 抽离菜单定义

为了方便后续维护,我们最好不把所有的功能都写在main.js中。比如菜单栏相关的代码,单独抽取成为一个menu.js。然后再引入到main.js中。

menu.js

const {BrowserWindow,Menu} = require('electron')
  
// 配置模板
const template = [
    {
        label: '文件',
        submenu: [
            {
                label: '新建窗口',
                click(){
                    new BrowserWindow({
                        width: 300,
                        height: 200
                    })
                }
            },
        {
            label: '保存'
        },
        {
            label: '另存为'
        },
        {
            label: '首选项'
        },
        {
            label: '退出'
        }
        ]
    },
    {
        label: '编辑'
    },
    {
        label: '关于我们'
    }
]

// 菜单对象构建该模板,生成菜单对象
const menu = Menu.buildFromTemplate(template);
// 设置我们构建好的菜单
Menu.setApplicationMenu(menu);

main.js

// 导入electron对象
// app 控制应用程序的事件生命周期。
// BrowserWindow 创建并控制浏览器窗口。
// Menu 创建原生应用菜单和上下文菜单。
const { app,BrowserWindow} = require('electron')

// 开启热加载
const reloader = require('electron-reloader')
reloader(module)


// 控制ready事件
// ready事件是:当 Electron 完成初始化时,发出一次。
app.on('ready',()=>{
  // 新建窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600
  });
  // 让主窗口加载文件 html文件
  mainWindow.loadFile('./src/index.html');

  // 引入自定义菜单
  require('./menu')
})

界面效果依然一样,这里就不展示了。

6.4 无边框菜单

我们不用原生的这种菜单方式,像QQ音乐这种,菜单是自定义的。其实实现起来也不复杂。只需要隐藏掉frame即可,然后自己写菜单结构和样式。如下:

我们发现移走了是移走了,可是现在也无法拖拽了,也没有自己的菜单怎么办?

别急,我们一步一步来实现,先自定义菜单。

在index.html中写上菜单的html,然后再为它写一个css样式。

最后是使它能够拖拽,追加css:-webkit-app-region: drag; 实现拖拽。

6.4.1 为无边框菜单添加新建窗口点击事件

上面我们已经实现了无边框的菜单栏,并且让它拥有了可拖拽能力。

下面我们还是要实现一下点击新建窗口弹出一个新的窗口。

这时,问题来了,之前我们都是在主进程中也就是main.js文件中,通过BrowserWindow对象实现的。

现在我们的菜单栏是在index.html文件中实现的,它是在一个渲染进程中。渲染进程是无法操作主进程的对象的。

想在渲染进程中使用主进程中才能使用的对象,这就必须先remote出来。

 

ok,重新运行一下,发现点击并没有反应,我们打开调试窗口看看,结果发现报错了。

他说require is not defined。

这是因为JavaScript中默认是不能使用require这些属于nodejs的东西的

如果想在JavaScript代码中使用nodejs的东西,就必须在主进程中开启node模块以及remote模块。

webPreferences: {
    // 开启node模块
    nodeIntegration: true,

    // 如果无法开启node模块,还是报这个错,那么请关闭下面这个配置项

    contextIsolation: false,


    // 开启remote模块
    enableRemoteModule: true
  }

这里要注意:electron12版本以后,默认是移除了remote的,官方推荐路由的方式来处理。如果想了解的建议直接去官网。这里我们还是选择用remote,既然官网移除了,那么我们再把它安装回来。

npm install @electron/remote --save

问题:

此时再次点击新建窗口,发现还是不能,这是为什么呢?

我们console.log("随便")随便打印点东西看看能否出现结果。结果无法展示出来,说明点击就没起作用。

而我们检查了语法又没有问题。

这是因为我们把整个菜单栏全部都设置成了拖拽功能了,所以才导致无法点击。

解决办法就是将li标签列表设置为不可拖拽。

6.4.2 小总结

总结使用无边框的菜单栏使用步骤:

1. main.js的主窗口中关闭frame。

2. 在对应渲染页面中编写菜单的html结构,并自己设置对应的css样式。

3. 记得在css样式合适的位置设置-webkit-app-region: drag;让其可拖拽,为保障菜单功能点击有效,记得在对应的名称上设置禁止拖拽-webkit-app-region: no-drag;否则父标签的拖拽效果会传递给子标签。

4. 给菜单添加点击事件。

5. 如果要让点击后弹窗,需要使用到Main进程的BrowserWindow。则需要remote出来。

6. 因此需要在主进程开启remote模块。

7. 同时要在js中使用nodejs的东西,则也需要开启node模块。

6.4.2 点击打开网页

同样的道理,我们再来试一试点击打开一个网页。

为了照顾到不同版本带来的remote差异,我们直接用原生的菜单栏。然后把原来自己写的自定义菜单栏html代码注释掉,免得影响美观。

七、打开对话框读取文件

为了照顾到不同版本带来的remote差异,我们直接用原生的菜单栏。然后把原来自己写的自定义菜单栏html代码注释掉,免得影响美观。接着给菜单栏增加一个子菜单:导入文件。

// 导入electron对象
// app 控制应用程序的事件生命周期。
// BrowserWindow 创建并控制浏览器窗口。
// Menu 创建原生应用菜单和上下文菜单。

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



// 开启热加载
const reloader = require('electron-reloader')
reloader(module)


// 控制ready事件
// ready事件是:当 Electron 完成初始化时,发出一次。
app.on('ready',()=>{
  // 新建窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    // 是否显示原生菜单栏
    frame: true,
    webPreferences: {
      // 开启node模块
      nodeIntegration: true,
      // 开启remote模块
      enableRemoteMoudle: true
    }
  });
  // 让主窗口加载文件 html文件
  mainWindow.loadFile('./src/index.html');

  // 引入自定义菜单
  require('./menu')


  // 自动打开调试窗口
  mainWindow.webContents.openDevTools();
})

引入dialog并展示,此时就弹出了对话框

下面我们看看可以填写哪些参数:dialog | Electron

由于时间有限,暂时整理到这里,如果有迫切的需要,请联系我,我会以你意想不到的速度进行补充。O(∩_∩)O

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/705934.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SpringBoot+vue的社区维修平台设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

信号链噪声分析19

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 用于定量表示 ADC 动态性能的常用指标有六个&#xff0c;分别是&#xff1a;SINAD&#xff08;信纳比&#xff09;、ENOB &#xff08;有效位数&#xff09;、SNR&#xff08;信…

keil_arm 大端小端 寄存器 栈

.text .global _start _start: /* 单寄存器ldr r0,0x40000800ldr r1,0x12345678将r1寄存器中的值&#xff0c;写到r0指向的地址空间中[0x40000800]0x12345678str r1,[r0]将r0指向地址空间中的内容&#xff0c;读到目标寄存器r2中&#xff0c;r20x12345678 ldr r2,[r0] */ /*ldr…

前端设计模式学习

UML类图 1.工厂模式 设计原则&#xff1a;最重要的就是开放封闭原则&#xff0c;对扩展开放&#xff0c;对修改封闭。 1.工厂和类分离&#xff0c;解耦 2.可以扩展多个类 3.工厂的创建逻辑也可以自由扩展 工厂模式可以拆分成三个&#xff0c;分别是工厂方法模式、抽象工厂…

C/C++图形库EasyX保姆级使用教程(二) 图形化窗口设置以及简单图形的绘制

C/C图形库EasyX保姆级使用教程 第一章 Microsoft Visual Studio 2022和EasyX的下载及安装使用 第二章 图形化窗口设置以及简单图形的绘制 文章目录 C/C图形库EasyX保姆级使用教程前言一、窗口&#xff01;1.如何生成一个图形化窗口&#xff1f;1.头文件2.初始化一个图形化窗口…

基于Java+Swing+Mysql人口普查登记系统

基于JavaSwingMysql人口普查登记系统 一、系统介绍二、功能展示1.主页2.新增人口信息3.查询人口信息 三、数据库四、其他系统实现五、获取源码 一、系统介绍 该系统实现了查看列表、新增人口信息、删除人口信息 运行环境&#xff1a;eclipse、idea、jdk1.8 二、功能展示 1.…

常州工学院数字图像处理及应用2022-2023第二学期实验报告 + 期末

《数字图像处理及应用》 课程 实验报告书 专业班级&#xff1a; 21计二 姓 名&#xff1a; 王梓权 学 号&#xff1a; 21030228 指导教师&#xff1a; 徐则中 计算机信息工程学院 《数字图像处理》实验 实验教学目的和要求 《数字图像处理》课程内容是一门综合…

Python MongoDB复习第一章

Python 可以在数据库应用程序中使用。 最受欢迎的 NoSQL 数据库之一是 MongoDB。 MongoDB MongoDB 将数据存储在类似 JSON 的文档中&#xff0c;这使得数据库非常灵活和可伸缩。 为了能够测试本教程中的代码示例&#xff0c;您需要访问 MongoDB 数据库。 您可以在 https:/…

论文学习笔记:增强学习应用于OS调度

【引子】周末&#xff0c;读了一篇同事推荐的论文《STUN: Reinforcement-Learning-Based Optimization of Kernel Scheduler Parameters for Static Workload Performance》&#xff0c;很有启发&#xff0c;遂加入个人思考编译成文。 从小型物联网设备到大型服务器&#xff0c…

VIM编辑器的命令使用总结

&#xff08;该图由AI绘制 关注我 学习AI画图&#xff09; 目录 一、VIM编辑器 1、vi概述 2、vim编辑器 3、vim编辑器的安装 4、vim编辑器的四种模式&#xff08;重点&#xff09; ☆ 命令模式 ☆ 编辑模式或输入模式 ☆ 末行模式 ☆ 可视化模式&#xff08;了解&am…

Apache Doris (十三) :数据存储模型之Duplicate数据存储模型

进入正文之前&#xff0c;欢迎订阅专题、对博文点赞、评论、收藏&#xff0c;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; 在某些多维分析场景下&#xff0c;数据既没有主键&#xff0c;也没有聚合需求&#xff0c;只需要将数据原封不动的存入表中&#xff0c;数据有…

神经网络初谈

文章目录 简介神经网络的发展历程神经网络的初生神经网络的第一次折戟神经网络的新生&#xff0c;Hinton携BP算法登上历史舞台命途多舛&#xff0c;神经网络的第二次寒冬神经网络的重生&#xff0c;黄袍加身&#xff0c;一步封神神经网络的未来&#xff0c;众说纷纭其他时间点 …

【实战】 四、JWT、用户认证与异步请求(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(五)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求1~56.用useAuth切换登录与非登录状态7.用fetch抽象通用HTTP请求方法&#xff0c;增强通用性8.用useHt…

基于Hadoop的网上购物行为分析设计与实现

有需要本项目的可以私信博主&#xff0c;提供部署和讲解服务&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 本研究基于淘宝用户行为的开源数据展开大数据分析研究&#xff0c;通过Hadoop大数据分析平台对阿里天池公开的开源数据集进行多维度的用户行为分析&a…

4.1ORB-SLAM3之处理缓存队列中的关键帧

0.简介 该函数主要包括以下几个部分&#xff1a; 计算该关键帧特征点的Bow信息更新当前关键帧新增地图点的属性更新共视图中关键帧间的连接关系将该关键帧插入到地图中 1.计算该关键帧特征点的Bow信息ComputeBoW() vector<cv::Mat> vCurrentDesc Converter::toDescr…

ModaHub魔搭社区:向量数据库功能主要特点和应用场景

目录 主要特点 向量数据库功能 高性能向量搜索 低延迟高召回率 多向量搜索索引 向量数据库可以帮助的领域 图像相似性搜索 视频相似性搜索 音频相似性搜索 主要特点 向量数据库功能 高性能向量搜索 存储、索引和管理由深度神经网络和其他机器学习&#xff08;ML&…

Matlab论文插图绘制模板第106期—带误差棒的堆叠柱状图

在之前的文章中&#xff0c;分享了Matlab带误差棒的折线图绘制模板&#xff1a; 带误差棒的柱状图绘制模板&#xff1a; 进一步&#xff0c;再来分享一下带误差棒的堆叠柱状图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源…

管理类联考——数学——技巧篇——公式——几何题

三角形 三角形面积公式 S 1 2 b c s i n A 1 2 a c s i n B 1 2 a b s i n C S\frac{1}{2}bcsinA\frac{1}{2}acsinB\frac{1}{2}absinC S21​bcsinA21​acsinB21​absinC(正弦定理)&#xff1b; S p ( p − a ) ( p − b ) ( p − c ) S\sqrt{p(p-a)(p-b)(p-c)} Sp(p−a)…

JAVA-编程基础-06-数组

Lison <dreamlison163.com>, v1.0.0, 2023.03.22 JAVA-编程基础-06-数组 什么是数组 ​ 数组是一种线性数据结构&#xff0c;是一个使用连续的内存空间存放相同的数据类型的集合容器&#xff0c;与其他容器相比&#xff0c;数组的区别主要在于性能与保存基本类型的能力…

ASUS华硕天选air笔记本FX516P原装出厂原厂Win10系统镜像

ASUS华硕笔记本天选air FX516P原厂Windows10系统恢复原装出厂OEM预装自带系统 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、华硕电脑管家、奥创控制中心等预装程序 链接&#xff1a;https://pan.baidu.com/s/150QimXQfATAhzxNCl690Nw?pwdhvj6 提取码&#xff1a;h…