• Electron基础学习笔记


    Electron基础学习笔记

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

    Electon概述

    • Electron 是由 Github开发的开源框架
    • 它允许开发者使用Web技术构建跨平台的桌面应用

    在这里插入图片描述

    Electron = Chromium + Node.js + Native API
    
    • 1
    • Chromium : 为Electron提供了强大的UI能力,可以不考虑兼容性的情况下,利用强大的Web生态来开发界面。
    • Node.js :让Electron有了底层的操作能力,比如文件的读写,甚至是集成C++等等操作,并可以使用大量开源的npm包来完成开发需求。
    • Native API : Native API让Electron有了跨平台和桌面端的原生能力,比如说它有统一的原生界面,窗口、托盘这些。
    什么时候使用Electron
    1. 公司没有专门的桌面应用开发者,而需要前端兼顾来进行开发时,用Electron就是一个不错的选择。
    2. 一个应用同时开发Web端和桌面端的时候,那使用Electron来进行开发就对了。
    3. 开发一些效率工具,比如说我们的VSCode,比如说一些API类的工具,用Electron都是不错的选择。
    有哪些著名应用是用Electron开发的
    • VSCode : 程序员最常用的开发者工具。
    • Atom : 是Github开发的文本编辑器,我想大部分的前端程序员都应该使用过。
    • slack : 聊天群组 + 大规模工具集成 + 文件整合 + 搜索的一个工具。就是把很多你常用的工具整合到了一起。
    • wordPress : 基于PHP开发的Blog搭建工具,新版本使用了Electron.

    Electron的Hello World案例

    安装Electron

    #项目内安装
    npm install electron --save-dev
    # 全局安装:
    npm install -g electron
    
    • 1
    • 2
    • 3
    • 4

    这个如果安装失败,可以多安装两遍,也可以使用cnpm来进行安装。

    新建index.html文件

    新建一个文件夹,比如叫ElectronDemo01.

    在项目的根目录中新建一个index.html文件,然后编写如下的代码(可以用快速生成的方式来写这段代码)。

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        Hello World!
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    新建main.js文件

    在根目录下新建一个main.js文件,这个就是Electron的主进程文件。

    var electron = require('electron')  //引入electron模块
     
    var app = electron.app   // 创建electron引用
     
    var BrowserWindow = electron.BrowserWindow;  //创建窗口引用
     
    var mainWindow = null ;  //声明要打开的主窗口
    app.on('ready',()=>{
        mainWindow = new BrowserWindow({width:400,height:400})   //设置打开的窗口大小
     
        mainWindow.loadFile('index.html')  //加载那个页面
     
        //监听关闭事件,把主窗口设置为null
        mainWindow.on('closed',()=>{
            mainWindow = null
        })
     
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    创建package.json文件

    写完后直接使用npm init --yes来初始化package.json文件,文件生成后如下:

    {
      "name": "ElectronDemo1",
      "version": "1.0.0",
      "description": "",
      "main": "main.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这时候main的值为main.js就正确了。这时候就可以打开终端,在终端里输入electron .就可以打开窗口了。

    若是在创建项目的时候就生成json文件,main对应的会是index.js,但是现在的话会生成main.js

    运行:

    electron.cmd .
    # 注意,后面有一个 .
    
    • 1
    • 2

    在这里插入图片描述

    Electron的运行流程

    • 1.读取package.json的中的入口文件(main定义的文件),这里我们是main.js
    • 2.main.js 主进程中创建渲染进程(loadFile)
    • 3.读取应用页面的布局和样式
    • 4.使用IPC在主进程执行任务并获取信息

    我们可以理解package.json中定义的入口文件就是主进程,那一般一个程序只有一个主进程,而我们可以利用一个主进程,打开多个子窗口.
    由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它自己的渲染进程中,也就是我们说的渲染进程.
    也就是说主进程控制渲染进程,一个主进程可以控制多个渲染进程.
    在这里插入图片描述

    案例2

    在项目根目录下建立一个xiaojiejie.txt的文件,然后写入几个小姐姐的名字.

    代码如下:

    1.麻里梨夏
    2.星野娜美
    3.高桥圣子
    
    • 1
    • 2
    • 3

    因为要使用node里的fs模块,所以在设置窗口时,增加全量使用node.js.

    var electron = require('electron')
     
    var app = electron.app
     
    var BrowserWindow = electron.BrowserWindow;
     
    var mainWindow = null ;
    app.on('ready',()=>{
        mainWindow = new BrowserWindow({
            width:500,
            height:500,
            webPreferences:{ nodeIntegration:true} //设置全局使用node.js
        })
     
        mainWindow.loadFile('index.html')
     
        mainWindow.on('closed',()=>{
            mainWindow = null
        })
     
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    index.html里边写一下界面.这里我们写了一个按钮,然后在按钮下方加一个

    ,这个DIV用来作读取过来内容的容器.

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, idivnitial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        
        <Button id="btn">小姐姐请进来Button><br/>
        <div  id="mybaby">div>
        <script src="renderer/index.js">script>
     
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    新建一个renderer文件夹,在文件里新建index.js,再index.html页面里先进行引入.
    编写index.js里的代码

    var fs = require('fs'); //引入node.js(需要在main.js中全局引入:webPreferences:{ nodeIntegration:true})
    window.onload = function(){//监听页面
        var btn = this.document.querySelector('#btn') //获取按钮
        var mybaby = this.document.querySelector('#mybaby') //获取显示的div
        btn.onclick = function(){ //点击按钮监听
            fs.readFile('xiaojiejie.txt',(err,data)=>{ //读取文件(默认项目根目录)
                mybaby.innerHTML = data //赋值
            })
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    Electron Remote模块的使用

    Electron有主进程和渲染进程,Electron的API方法和模块也是分为可以在主进程和渲染进程中使用.如果想在渲染进程中使用主进程中的模块方法时,可以使用Electron Remote解决在渲染和主进程间的通讯。
    新建一个demo2.html文件,然后快速生成html的基本结构,编写一个按钮,引入渲染的js页面。

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <Button id="btn">打开新的窗口Button><br/>
        <script src="renderer/demo2.js">script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    render文件夹下,新建一个demo2.js文件,然后编写如下代码。

     const btn = this.document.querySelector('#btn')
     const BrowserWindow =require('electron').remote.BrowserWindow
     
    window.onload = function(){
        btn.onclick = ()=>{
     
             newWin = new BrowserWindow({
                 width:500,
                 height:500,
             })
             newWin.loadFile('yellow.html')
             newWin.on('close',()=>{win=null})
     
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    yellow.html

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, idivnitial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        yellow
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    创建菜单和基本使用

    编写菜单模板

    Electron中编写菜单,需要先建立一个模板,这个目标很类似我们JSON或者类的数组。
    我们打开项目,在项目的根目录下新建一个文件夹main,意思是主进程中用到的代码我们都写到这里。
    然后新建一个menu.js文件,然后编写如下代码。

    //放所有菜单的操作
    const { Menu,BrowserWindow } = require('electron')
    //所有的菜单
    var template = [
        {
            label:'凤来怡洗浴会所',//菜单
            submenu:[//子菜单
                {label:'精品SPA',
                click:()=>{  //设置点击事件,使用的是electron的功能
                    win = new BrowserWindow({//创建新窗口
                        width:500,
                        height:500,
                        webPreferences:{ nodeIntegration:true}
                    })
                    win.loadFile('yellow.html')
                    win.on('closed',()=>{//监听关闭事件
                        win = null
                    })
     
                }
            },
                {label:'泰式按摩'}
            ]
     
        },
        {
            label:'大浪淘沙洗浴中心',
            submenu:[
                {label:'牛奶玫瑰浴'},
                {label:'爱情拍拍手'}
            ]
        }
    ]
    //构建菜单模板
    var m = Menu.buildFromTemplate(template)
    //设置菜单模板
    Menu.setApplicationMenu(m)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    然后再打开主进程main.js文件,在ready生命周期中,直接加入下面的代码,就可以实现自定义菜单了。

     require('./main/menu.js') //在引入页面之前加,比如:
     
    var electron = require('electron')  //引入electron模块
     
    var app = electron.app   // 创建electron引用
     
    var BrowserWindow = electron.BrowserWindow;  //创建窗口引用
     
    var mainWindow = null ;  //声明要打开的主窗口
    app.on('ready',()=>{
        mainWindow = new BrowserWindow({
            width:400,height:400,
            webPreferences:{ nodeIntegration:true}//全局引用node.js
        })   //设置打开的窗口大小
        //----------------------
        require('./main/menu.js')//引入自定义的菜单
        //------------------------
        mainWindow.loadFile('demo2.html')  //加载那个页面,使用新页面
        //监听关闭事件,把主窗口设置为null
        mainWindow.on('closed',()=>{
            mainWindow = null
        })
     
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    注意:Menu属于是主线程下的模块,所以只能在主线程中使用。
    在这里插入图片描述

    绑定快捷键

    绑定快捷键的属性是accelerator属性,比如我们新打开一个窗口,我们就的代码可以写成这样。

    accelerator:`ctrl+n`
    
    • 1

    例如:

    const { Menu ,BrowserWindow} = require('electron')
    var template = [
        {
            label:'凤来怡洗浴会所',
            submenu:[
                {
                    label:'精品SPA',
                    accelerator:`ctrl+n`,  //设置快捷键
                    click:()=>{
                        win = new BrowserWindow({
                            width:500,
                            height:500,
                            webPreferences:{ nodeIntegration:true}
                        })
                        win.loadFile('yellow.html')
                        win.on('closed',()=>{
                            win = null
                        })
     
                    }
                },
                {label:'泰式按摩'}
            ]
     
        },
        {
            label:'大浪淘沙洗浴中心',
            submenu:[
                {label:'牛奶玫瑰浴'},
                {label:'爱情拍拍手'}
            ]
        }chengxu
    ]
    var m = Menu.buildFromTemplate(template)
    Menu.setApplicationMenu(m)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    右键菜单

    右键菜单的响应事件是写在渲染进程中的,也就是写在index.html中的,所以要是使用,就用到到remote模块进行操作了。

    打开render文件夹,然后打开demo2.js文件,编写一个右键菜单的监听事件

    window.addEventListener('contextmenu',function(){
        alert(111);
    })
    
    • 1
    • 2
    • 3

    例如

    const btn = this.document.querySelector('#btn')
    const BrowserWindow =require('electron').remote.BrowserWindow  //
     
    window.onload = function(){
       btn.onclick = ()=>{//点击按钮,打开一个窗口,打开页面
     
            newWin = new BrowserWindow({
                width:500,
                height:500,
            })
            newWin.loadFile('yellow.html')
            newWin.on('close',()=>{win=null})
     
        }
    }
    //监听右键点击事件-------------
    window.addEventListener('contextmenu',function(){
        alert(111);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    当我们要使用Menu模块,它是主线中的模块,如果想在渲染线程中使用,就必须使用remote

    //引入remote就可以使用了
    const { remote} = require('electron')
    //右键的菜单
    var rigthTemplate = [
        {label:'粘贴',accelerator:`ctrl+c`},//菜单,快捷键
        {label:'复制'}
    ]
    //声明菜单
    var m = remote.Menu.buildFromTemplate(rigthTemplate)
    //监听右键点击事件-------------
    window.addEventListener('contextmenu',function(e){
     
        //阻止当前窗口默认事件
        e.preventDefault();
        //把菜单模板添加到右键菜单,弹出右键菜单
        m.popup({window:remote.getCurrentWindow()})
     
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    打开调试模式

    由于我们已经定义了顶部菜单,没有了打开调试模式的菜单了,这时候可以使用程序来进行打开。在主进程中加入这句代码就可以了。

    mainWindow.webContents.openDevTools()
    
    • 1

    全部代码如下:

    var electron = require('electron') 
     
    var app = electron.app   
     
    var BrowserWindow = electron.BrowserWindow;
     
    var mainWindow = null ;
    app.on('ready',()=>{
        mainWindow = new BrowserWindow({
            width:500,
            height:500,
            webPreferences:{ nodeIntegration:true}
        })
        mainWindow.webContents.openDevTools()  //打开调试模式
     
        require('./main/menu.js')
     
        mainWindow.loadFile('demo2.html')
     
        mainWindow.on('closed',()=>{
            mainWindow = null
        })
     
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    这样就实现了打开窗口,直接进入调试模式,极大的提高了调试效率。

    Electron 中使用shell通过链接打开浏览器

    在渲染进程中默认加入一个标签,进行跳转默认是直接在窗口中打开,而不是在浏览器中打开的,如果我们想在默认浏览器中打开,要使用electron shell在浏览器中打开链接。

    案例:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <h1>
            
            <a href="https://jspang.com">技术胖的博客a>
            
            <a id="aHref" href="https://jspang.com">技术胖的博客a>
        h1>
        <script src="./renderer/demo3.js">script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    如果想使用浏览器打开,我们可以直接在标签中加入id,然后在render文件夹下,新建一个demo3.js文件,先在文件首页中引入shell,然后编写响应事件click

    var { shell } = require('electron')  //需要使用的是shell
     
    var aHref = document.querySelector('#aHref')
     
    aHref.onclick = function(e){
        e.preventDefault() //组织默认行为
        var href = this.getAttribute('href') //获取连接
        shell.openExternal(href) //打开连接
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Electron 中嵌入网页和打开子窗口

    用BrowserView来嵌入一个网页到应用中,这很类似Web中的