【前端】-【electron】

news2024/10/7 12:23:47

文章目录

  • 介绍
    • electron工作流程
    • 环境搭建
  • electron生命周期(app的生命周期)
  • 窗口尺寸
  • 窗口标题
  • 自定义窗口的实现
  • 阻止窗口关闭
  • 父子及模态窗口
  • 自定义菜单

介绍

electron技术架构:chromium、node.js、native.apis
在这里插入图片描述

electron工作流程

在这里插入图片描述
桌面应用就是运行在不同操作系统上的软件,软件中的功能是通过native.apis跟不同操作系统进行交互实现的,想实现什么功能调用响应的API即可
electron主要有两类进程:

  1. 主进程:main process
  2. 渲染进程:renderer process

当我们启动一个APP时,他首先会启动主进程,一般是main.js或index.js中的代码,主进程启动成功后会创建一个native ui,然后在nativeui里创建一个或多个Browse window,用于呈现界面(即web界面),每个Browse window可以看作是一个渲染进程,每个渲染进程相互独立,各自运行在自己的沙箱环境中,但是app在使用的过程中,不同窗口会进行交互,于是electron提供了IPC、RPC通信机制供窗口与窗口进行数据传输
在这里插入图片描述
只有主进程能操作原生API,能管理所有WEB界面,和这些web界面对应的渲染进程
在这里插入图片描述
渲染进程支持所有的DOM操作、node api的调用操作

环境搭建

package.json中main字段指定的文件就是app启动后,启动的主进程;script字段指定的是启动项目的命令
在这里插入图片描述

electron生命周期(app的生命周期)

ready:app初始化完成后会被调用一次,一般用于窗口初始化
dom-ready:一个窗口中的文本加载完成,与dom操作相关,有个webcontext对象可以调用
did-finsh-load:导航完成时触发,即选项卡的旋转器停止旋转时触发,且指派了onload事件。由webcontext调用
window-all-closed:所有窗口都被关闭时触发,如果我们没有监听这个方法,那么所有窗口关闭后,应用程序就默认退出,如果我们监听了这个方法,我们就可以自己决定所有窗口关闭后,应用程序是否退出,如果我们选择不退出,那么后续的before-quit、will-quit、quit都失效了
before-quit:在关闭窗口之前触发
will-quit:在窗口关闭并且应用退出时触发
quit:所有窗口被关闭时触发
closed:当窗口关闭时触发,此时应删除窗口引用

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

// 创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
        width: 800,
        height:400
    })

    mainWindow.loadFile('index.html')

    // webContents用于操作dom
    mainWindow.webContents.on('did-finish-load',() => {
        console.log("33333------did-finish-load")
    })
    mainWindow.webContents.on('dom-ready',() => {
        console.log("22222------dom-ready")
    })

    mainWindow.on('close',() => {
        console.log("88888------close")
        mainWindow = null
    })
}

app.on('ready',() => {
    console.log("11111------ready")
    createWindow()
})

app.on('window-all-closed',() => {
    console.log("44444------window-all-closed")
})

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

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

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

执行顺序:1——2——3——8——4——5——6——7

窗口尺寸

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

// 创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
        x:100,// 设置窗口显示的位置,距离左边的距离
        y:100,// 设置窗口显示的位置,距离右边的距离
        width: 800,
        height:400,
        maxHeight:600,// 窗口最大高度
        minHeight:200,// 窗口最小高度
        maxWidth:1000,// 窗口最大宽度
        minWidth:300,// 窗口最小宽度
        resizable:false// 是否允许缩放窗口,默认为true,可以缩放窗口,设为false
    })

    mainWindow.loadFile('index.html')

    mainWindow.on('close',() => {
        console.log("88888------close")
        mainWindow = null
    })
}

app.on('ready',createWindow)

app.on('window-all-closed',() => {
    console.log("window-all-closed")
    app.quit()
})

注意此时有个bug:窗口弹出来,然后有一段白屏时间,然后再出现内容,这是因为let mainWindow = new BrowserWindow()执行完成后就会显示出窗口来,此时窗口里面是没有内容的,我们设置show:false,让窗口创建好也不展示出来,然后加载index.html文件,加载完成后,监听窗口的ready-to-show方法,再把窗口展示出来

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

// 创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
    	show:false,
        width: 800,
        height:400
    })

    mainWindow.loadFile('index.html')
    // 监听窗口已经准备好去展示了
	mainWindow.on('ready-to-show',()=>{
		mainWindow.show()
	})
    mainWindow.on('close',() => {
        console.log("88888------close")
        mainWindow = null
    })
}

app.on('ready',createWindow)

app.on('window-all-closed',() => {
    console.log("window-all-closed")
    app.quit()
})

窗口标题

在这里插入图片描述

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

// 创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
    	show:false,
        width: 800,
        height:400,
        frame: false,// 是否有边框
        transparent:true,// 窗体透明,只有frame: false时才生效
        icon:'lg.ico',// 图标
        title:'拉钩教育',// 窗口标题
        autoHideMenuBar: true// 隐藏菜单、选项卡
    })

    mainWindow.loadFile('index.html')
    // 监听窗口已经准备好去展示了
	mainWindow.on('ready-to-show',()=>{
		mainWindow.show()
	})
    mainWindow.on('close',() => {
        console.log("88888------close")
        mainWindow = null
    })
}

app.on('ready',createWindow)

app.on('window-all-closed',() => {
    console.log("window-all-closed")
    app.quit()
})

需求:窗口里面提供一个按钮,点击按钮,再弹出一个窗口

ctr+r可以对应用进行重载
25版本后可以使用ipcMain和ipcRenderer实现新窗口

index.html代码如下:
在这里插入图片描述
版本一:主进程允许渲染进程使用BrowserWindow实现,main.js代码如下:

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

// 创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
    	show:false,
        width: 800,
        height:400,
        webPreferences:{
            nodeIntegration:true,// 允许渲染进程使用node集成环境
            contextIsolation: false,// 如果nodeIntegration:true失效,那么需要添加这行代码 
        }
    })

    mainWindow.loadFile('index.html')
    // 监听窗口已经准备好去展示了
	mainWindow.on('ready-to-show',()=>{
		mainWindow.show()
	})
    mainWindow.on('close',() => {
        console.log("88888------close")
        mainWindow = null
    })
}

app.on('ready',createWindow)

app.on('window-all-closed',() => {
    console.log("window-all-closed")
    app.quit()
})

index.js代码(index.html的js代码)如下:
在这里插入图片描述
版本二:主进程允许渲染进程使用remote实现,main.js代码如下:

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

// 创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
    	show:false,
        width: 800,
        height:400,
        webPreferences:{
            enableRemoteModule:true//允许使用远程模式
        },
        autoHideMenuBar: true// 隐藏菜单、选项卡
    })

    mainWindow.loadFile('index.html')
    // 监听窗口已经准备好去展示了
	mainWindow.on('ready-to-show',()=>{
		mainWindow.show()
	})
    mainWindow.on('close',() => {
        console.log("88888------close")
        mainWindow = null
    })
}

app.on('ready',createWindow)

app.on('window-all-closed',() => {
    console.log("window-all-closed")
    app.quit()
})

index.js代码(index.html的js代码)如下:

const { remote } = require('electron')
window.addEventListener('DOMContentLoaded',() => {
    // 点击按钮打开一个新窗口
    const oBtn = document.getElementsById('btn')
    oBtn.addEventListener('click',() => {
        // 创建窗口
        let indexWindow = new remote.BrowserWindow({
            width:200,
            height:200
        })
        indexWindow.loadFile('sub.html')
        indexWindow.on('close',() => {
            indexWindow = null
        })
    })
})

自定义窗口的实现

需求:点击窗口右上角的三个图标,分别执行相应操作
在这里插入图片描述
index.html代码如下,红框中为三个图标的代码
在这里插入图片描述
main.js中代码如下:

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

// 创建窗口
function createWindow() {
    let mainWindow = new BrowserWindow({
    	show:false,
        width: 800,
        height:400,
        webPreferences:{
            nodeIntegration:true,// 允许渲染进程使用node集成环境
            contextIsolation: false,// 如果nodeIntegration:true失效,那么需要添加这行代码
            enableRemoteModule:true//允许使用远程模式
            
        },
        autoHideMenuBar: true// 隐藏菜单、选项卡
    })

    mainWindow.loadFile('index.html')
    // 监听窗口已经准备好去展示了
	mainWindow.on('ready-to-show',()=>{
		mainWindow.show()
	})
    mainWindow.on('close',() => {
        console.log("88888------close")
        mainWindow = null
    })
}

app.on('ready',createWindow)

app.on('window-all-closed',() => {
    console.log("window-all-closed")
    app.quit()
})

index.html的js代码写在index.js中,如下:

const { remote } = require('electron')
window.addEventListener('DOMContentLoaded',() => {
    // 利用remote可以获取当前窗口对象
    let mainWindow = remote.getCurrentWindow()
    // 获取元素添加点击操作的监听
    let aBtn = document.getElementsByClassName('windowTool')[0].getElementsByTagName('div')

    aBtn[0].addEventListener('click',() => {
        // 关闭窗口
        mainWindow.close()
    })

    aBtn[1].addEventListener('click',() => {
        // 最大化
        console.log(mainWindow.isMaximized())
        // 先判断当前窗口是不是最大化,如果是,则回到原来的大小,如果不是最大化,则最大化当前窗口
        if(!mainWindow.isMaximized()){
            mainWindow.maximize()// 让当前窗口最大化
        }else{
            mainWindow.restore()// 让当前窗口回到原来的大小
        }
    })

    aBtn[2].addEventListener('click',() => {
        // 最小化
        console.log(mainWindow.isMinimized())
        if(!mainWindow.isMaximized()){
            mainWindow.minimize()// 让当前窗口最小化
        }
    })
})

阻止窗口关闭

点击右上角的关闭按钮后,弹出浮窗提示用户是否关闭,若用户选择关闭,则关闭应用,否则关闭浮窗,index.html页面如下:
在这里插入图片描述
index.html中的js代码保存在index.js中,代码如下:

const { remote } = require('electron')
window.addEventListener('DOMContentLoaded',() => {

    // 监听mainWindow.close()
    window.onbeforeunload = function(){
        let oBox = document.getElementsByClassName('isClose')[0]
        oBox.style.display = 'block'// 弹窗出现
        let yseBtn = oBox.getElementsByTagName('span')[0]
        let noBtn = oBox.getElementsByTagName('span')[1]
        yseBtn.addEventListener('click', () => {
            // 此时关闭窗口需要用destory,
            // 因为onbeforeunload用于监听mainWindow.close(),如果这里还用mainWindow.close关闭的话,会陷入死循环
            mainWindow.destory()
        })
        noBtn.addEventListener('click', () => {
            oBox.style.display = 'none'// 去掉弹窗
        })
    }
    // 利用remote可以获取当前窗口对象
    let mainWindow = remote.getCurrentWindow()
    // 获取元素添加点击操作的监听
    let aBtn = document.getElementsByClassName('windowTool')[0].getElementsByTagName('div')

    aBtn[0].addEventListener('click',() => {
        // 关闭窗口
        mainWindow.close()
    })

    aBtn[1].addEventListener('click',() => {
        // 最大化
        console.log(mainWindow.isMaximized())
        // 先判断当前窗口是不是最大化,如果是,则回到原来的大小,如果不是最大化,则最大化当前窗口
        if(!mainWindow.isMaximized()){
            mainWindow.maximize()// 让当前窗口最大化
        }else{
            mainWindow.restore()// 让当前窗口回到原来的大小
        }
    })

    aBtn[2].addEventListener('click',() => {
        // 最小化
        console.log(mainWindow.isMinimized())
        if(!mainWindow.isMaximized()){
            mainWindow.minimize()// 让当前窗口最小化
        }
    })
})

父子及模态窗口

在这里插入图片描述
index.js代码如下:

const { remote } = require('electron')
window.addEventListener('DOMContentLoaded',() => {
    // 点击按钮打开一个新窗口
    const oBtn = document.getElementsById('btn')
    oBtn.addEventListener('click',() => {
        // 创建窗口
        let indexWindow = new remote.BrowserWindow({
            parent:remote.getCurrentWindow(),// 指定子窗口的父窗口是主线程的窗口
            modal:true,// 子窗口是模态化窗口,当子窗口出现时,父窗口不能游任何操作,也不能移动
            width:200,
            height:200
        })
        indexWindow.loadFile('sub.html')
        indexWindow.on('close',() => {
            indexWindow = null
        })
    })
})

自定义菜单

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

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

相关文章

SQL Server 2016(为数据表Porducts添加数据)

1、实验环境。 某公司有一台已经安装了SQL Server 2016的服务器,并已经创建了数据库PM。 2、需求描述。 在数据库PM中创建表products,"编号"列的值自动增长并为主键。然后使用T-SQL语句为表格插入如下数据。 3、实验步骤。 1、使用SSMS管理工…

2022年高校大数据挑战赛B题图像信息隐藏求解全过程论文及程序

2022年高校大数据挑战赛 B题 图像信息隐藏 原题再现: 互联网的快速发展,给图像、视频的传播方式带来巨大变化。图像作为媒体的重要载体,每天有大量的原创图像公开在互联网上,如何保护图像版权的同时不破坏原始的图像一直是图像处…

反转链表的实现

题目描述: 给出一个链表的头节点,将其反转,并返回新的头节点 思路1:反转地址 将每个节点里的地址由指向下一个节点变为指向前一个节点 定义三个结构体指针n1,n2,n3,n1表示改后指针的地址,n2表示要修改结构体里next的…

手机上的记事本怎么打开?安卓手机通用的记事本APP

有不少上班族发现,自己想要在电脑上随手记录一些工作文字内容,直接使用电脑上的记事本工具来编辑文字是比较便捷的。但是如果想要在手机上记录文字内容,就找不到手机上的记事本了。那么手机上的记事本怎么打开?安卓手机通用的记事…

AWS Remote Control ( Wi-Fi ) on i.MX RT1060 EVK - 1 “建立开发环境”

这个系列的文章将叙述如何借由 NXP 的“evkmimxrt1060_aws_remote_control_wifi_nxp”这支 Sample Code,达到 NXP RT1060EVK 经由 U-Blox EVK-JODY-W263 将资讯传到 AWS 上,并可借由手机对 RT1060 EVK 的 LED 进行远端控制。 整体架构如下图所示&#x…

VUE语法-(readonly的用法)将数据设置成只读模式

1、功能概述 在Vue中定义一个变量,这个变量的值不允许被修改,核心是通过readonly设置成只读。 如果不会使用ref和reactive响应式数据参考如下博客: https://blog.csdn.net/tangshiyilang/article/details/134701103 2、具体实现 如下案例…

41 - 如何使用缓存优化系统性能?

缓存是我们提高系统性能的一项必不可少的技术,无论是前端、还是后端,都应用到了缓存技术。前端使用缓存,可以降低多次请求服务的压力;后端使用缓存,可以降低数据库操作的压力,提升读取数据的性能。 今天我…

LeetCode | 965. 单值二叉树

LeetCode | 965. 单值二叉树 OJ链接 首先判断树为不为空,为空直接true然后判断左子树的val,和根的val相不相同再判断右子树的val,和根的val相不相同最后递归左子树和右子树 bool isUnivalTree(struct TreeNode* root) {if(root NULL)retur…

windows下如何搭建属于自己的git服务器?

windows下如何搭建属于自己的git服务器? 工具准备(此章节为网上摘要,忘记出自哪里了,大家自行参考)实操步骤 工具准备(此章节为网上摘要,忘记出自哪里了,大家自行参考) …

c语言详解牛顿迭代法以及求解倒数和平方根

Newtons iteration method 是在实数域和复数域利用切线不断逼近方程根的一种求高次曲线方程的方法,区别于梯度下降法,它是二阶导,收敛速度比较快,对于非凸函数,牛顿法容易受到鞍点或者最大值点的吸引。由于牛顿迭代法是…

[英语学习][3][Word Power Made Easy]的精读与翻译优化

[序言] 这次翻译校验, 难度有点大, 原版中英翻译已出现了严重地偏差. 昨晚11点开始阅读如下段落, 花费了1个小时也没有理解原作者的核心表达, 索性睡觉了. 今早学习完朗文单词之后, 9点半开始继续揣摩. 竟然弄到了中午11点30, 终于明白原作者要表达的意思了. 废话不多说&#x…

笔记----单纯剖分----1

笔记----单纯剖分 定义 线性组合仿射组合: 线性组合的系数为1凸组合: 仿射组合所有的系数都是正数 凸集 R^m 的 任意有限个点的凸组合仍在其中的子集仿射子空间 R^m 的 任意有限个点的仿射组合仍在其中的子集凸包 conv(A) A是R^m的一个子集 A的所有有限凸…

【小布_ORACLE笔记】Part11-6 RMAN Backups

【小布_ORACLE笔记】Part11-6 RMAN Backups 1.track文件的作用 当做差异性备份时,server process对应的RMAN客户端的server process就不用去每个块每个块的检查,只要到trackfile 里面去读一下,看哪个块改变了就直接把哪个块备份下来&#x…

轻量封装WebGPU渲染系统示例<40>- 多层材质的Mask混合(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/MaskTextureEffect.ts 当前示例运行效果: 两层材质效果: 三层材质效果: 此示例基于此渲染系统实现,当前示例TypeScript源码如下: export c…

【Go】protobuf介绍及安装

目录 一、Protobuf介绍 1.Protobuf用来做什么 2. Protobuf的序列化与反序列化 3. Protobuf的优点和缺点 4. RPC介绍 <1>文档规范 <2>消息编码 <3>传输协议 <4>传输性能 <5>传输形式 <6>浏览器的支持度 <7>消息的可读性和…

【鸿蒙应用ArkTS开发系列】-自定义底部菜单列表弹窗

文章目录 前言创建Demo工程创建dialog 文件夹创建ListMenu 接口创建自定义弹窗 ListMenuDialog使用自定义弹窗 打包测试效果演示默认效果菜单带图标效果设置文本颜色效果不同文本颜色效果无标题效果 前言 上一篇文章中我们实现了选择图片、选择文件、拍照的功能 。 链接在这里…

11.28 C++作业

提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 要求使用C风格字符串完成 #include <iostream>using namespace std;int main() {string str;cout << "请输入一个字符串&#xff1a;" <<…

92基于matlab的引力搜索算法优化支持向量机(GSA-SVM)分类模型

基于matlab的引力搜索算法优化支持向量机&#xff08;GSA-SVM&#xff09;分类模型&#xff0c;以分类精度为优化目标优化SVM算法的参数c和g&#xff0c;输出分类可视化结果及适应度变化曲线。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 92 引力搜索算法…

无人机助力电力设备螺母缺销智能检测识别,python基于YOLOv5开发构建电力设备螺母缺销小目标检测识别系统

传统作业场景下电力设备的运维和维护都是人工来完成的&#xff0c;随着现代技术科技手段的不断发展&#xff0c;基于无人机航拍飞行的自动智能化电力设备问题检测成为了一种可行的手段&#xff0c;本文的核心内容就是基于YOLOv7来开发构建电力设备螺母缺销检测识别系统&#xf…

Symbol()和迭代器生成器

目录 1、Symbol&#xff08;&#xff09; 2、迭代器生成器 执行流程 模拟生成器函数 for of 遍历迭代选择器 yield * Generator函数应用 1、Symbol&#xff08;&#xff09; Symbol表示独一无二的值 const s1 Symbol(a)const s2 Symbol(a)console.log(s1 s2) // fa…