【前端】-【electron】

文章目录

介绍

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:当窗口关闭时触发,此时应删除窗口引用

javascript 复制代码
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

窗口尺寸

javascript 复制代码
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方法,再把窗口展示出来

javascript 复制代码
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()
})

窗口标题

javascript 复制代码
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代码如下:

javascript 复制代码
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代码如下:

javascript 复制代码
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代码)如下:

javascript 复制代码
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中代码如下:

javascript 复制代码
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中,如下:

javascript 复制代码
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中,代码如下:

javascript 复制代码
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代码如下:

javascript 复制代码
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
        })
    })
})

自定义菜单

相关推荐
一颗花生米。3 小时前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
学习使我快乐013 小时前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio19953 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
勿语&4 小时前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
黄尚圈圈4 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水5 小时前
简洁之道 - React Hook Form
前端
正小安7 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch9 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光9 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js