[前端开发]PC桌面端-Electron学习笔记

Electron快速上手

基础模板改造

git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install && npm start

脚手架工具开发

https://github.com/electron-userland/electron-forge
npx create-electron-app electronApp
或者
yarn create electron-app electronApp
image.png

进程调度

Electron 中, 与 GUI 相关的模块(如 dialog, menu 等)只存在于主进程,而不在渲染进程中 。 为了能从渲染进程中使用它们,需要用 ipc模块来给主进程发送进程间消息。使用 remote 模 块,可以调用主进程对象的方法

mainWindow=new BrowserWindow({width:800,height:600,webPreferences: { 
 nodeIntegration: true,//开启渲染进程中使用nodejs
 enableRemoteModule: true//
 }});
    mainWindow.loadFile(path.join(__dirname, "new_render.html"));

顶部菜单,右键菜单

https://www.electronjs.org/docs/api/menu-item
顶部菜单是在主进程中运行,所以需要在main.js调用。
右键菜单是在渲染进程中运行,所以需要在html文件中运行。

//顶部菜单  src/ipcMain/menu.js
const { Menu } = require("electron");
var topMenu=[
    {
        label:"文件",
        submenu:[
            {
                label:"新建",
                accelerator:"ctrl+n",
                click:()=>{
                    console.log("Ctrl+N")
                }
            },
            {
                type:"separator"
            },
            {
                label:"保存"
            }
        ]
    },
    {
        label:"编辑",
        submenu:[
            {
                label:"复制",
                role:"copy",
                click:()=>{
                    console.log("copy")
                }
            }         
        ]
    }
];
var menuBuilder=Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menuBuilder);
//src/main.js
const createWindow = () => {    
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences:{
            nodeIntegration:true,
            enableRemoteModule:true
        }
    });
    //在渲染进程中开启调试模式
    mainWindow.webContents.openDevTools()
    mainWindow.loadFile(path.join(__dirname, "index.html"));
    //自定义顶部菜单
    require('./ipcMain/menu');
}

鼠标右键菜单内容同上,只不过需要在index.html渲染进程中引入,且需要通过remote调用主进程中的menu模块

//渲染进程
const { remote } = require("electron");
const Menu = remote.Menu;
....
window.onload = () => {
    window.addEventListener("contextmenu", (e) => {
        e.preventDefault();
      //弹出右键差菜单
        menuBuilder.popup({window:remote.getCurrentWindow()});
    }, false)
}

主进程与渲染进程间通信

Electron 主进程和渲染进程的通信主要用到两个模块:ipcMain 和 ipcRenderer

ipcMain:当在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息, 当然也有可能从主进程向渲染进程发送消息。
ipcRenderer: 使用它提供的一些方法从渲染进程 (web 页面) 发送同步或异步的消息到主 进程。 也可以接收主进程回复的消息。

渲染进程给主进程发送异步消息:

const { ipcRenderer } = require('electron') ;
ipcRenderer.send('render2Main',{name:'steven'}); //渲染进程发送异步消息到主进程
ipcRenderer.on("main2render",(event,data)=>{
  console.log("主进程响应给渲染进程的数据",data);
})

//主进程监听渲染进程传递过来的数据,并发送消息给渲染进程
const { ipcMain } = require('electron'); 
ipcMain.on("render2Mainsg",(event,arg) => { 
console.log("渲染进程传递过来的数据",arg)
event.sender.send("main2render","主进程收到渲染进程发的异步消息")})

渲染进程给主进程发送同步消息

//渲染进程
const { ipcRenderer } = require('electron');
 const msg = ipcRenderer.sendSync('msg-a'); 
console.log(msg) 
//主进程
 ipcMain.on('msg-a',(event)=> { event.returnValue = 'hello'; })

主进程通知渲染进程执行操作

//主进程 
BrowserWindow.getFocusedWindow().webContents.send('replay','new 111');

//渲染进程 
const { ipcRenderer } = require('electron');
ipcRenderer.on('reply', function(event, arg) { console.log(arg);});

渲染进程和渲染进程之间通信

  • LocalStorage使数据两个html页面之间传递数据
  • 通过 BrowserWindow 和 webContents 模块实现渲染进 程和渲染进程的通信
    https://www.electronjs.org/docs/api/web-contents
    每个新窗口都是一个新的html页面,都对应一个窗口对象,可以通过下面的方式获取每个窗口的id
const winId = BrowserWindow.getFocusedWindow().id;
let win = BrowserWindow.fromId(winId); //获取到对应id的BroswerWindow对象
//在index.html开启打开另一个窗口的权限
let indexWinId ;
ipcMain.on("openNews",(event,data)=>{//渲染进程发出打开另一个窗口的事件:openNews
indexWinId  = BrowserWindow.getFocusedWindow().id;
    const newsWindow= new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences:{
            nodeIntegration:true,
            enableRemoteModule:true
        }
    });
    //在渲染进程中开启调试模式
    newsWindow.webContents.openDevTools()
    newsWindow.loadFile(path.join(__dirname, "news.html"));
    //监听当前窗口加载完成的事件
    newsWindow.webContents.on('did-finish-load',(event) => { 
       newsWindow.webContents.send('msg',winId,'我是 index.html 的数据'+data);
     })
}
//主进程通过index.html的winID给index.html渲染进程回消息
   let mainWin = BrowserWindow.fromId(indexId);
    mainWin.webContents.send("toIndex",data)

Electron 中嵌入网页

https://www.electronjs.org/docs/api/shell //打开网页
https://www.electronjs.org/docs/tutorial/web-embeds //嵌入网页

var {shell}=require('electron') ;
shell.openExternal('https://github.com');

Important Note: we do not recommend you to use WebViews, as this tag undergoes dramatic architectural changes that may affect stability of your application. Consider switching to alternatives, like iframe and Electron's BrowserView, or an architecture that avoids embedded content by design.

官方建议使用iframe代替作为显示网页的容器

electron对话框

https://www.electronjs.org/docs/api/dialog

任务栏图标及菜单右键

https://www.electronjs.org/docs/api/tray

var { Menu, Tray,app,BrowserWindow } = require('electron');
var appIcon = new Tray(path.join(__dirname,'logo.png'));

const menu = Menu.buildFromTemplate( [
  { label: '设置', click: function () {} },
  { label: '退出', click: function () { //         
      BrowserWindow.getFocusedWindow()
                   .webContents()
                  .send('close-main-window'); 
             app.quit();
     } 
  } 
]);

appIcon.setToolTip('logo 鼠标移入title');
appIcon.setContextMenu(menu);

应用窗口

https://www.electronjs.org/docs/api/browser-window

  • 窗口关闭 :close
  • 最小化事件: 'minimize'
  • 事件: 'maximize'
const currWindow= BrowserWindow.getFocusedWindow(); 
currWindow.on('close',(e)=>{ 
     if(!currWindow.isFocused()){ 
        currWindow=null;
     }else{
        e.preventDefault(); /*阻止应用退出*/
       currWindow.hide(); /*隐藏当前窗口*/
     }
 })

全局快捷键&剪贴板

https://www.electronjs.org/docs/api/global-shortcut
https://www.electronjs.org/docs/api/clipboard
globalShortcut 模块可以在操作系统中注册/注销全局快捷键, 以便可以为操作定制各种快捷键

隐藏工具栏和自定义窗口操作区域

var mainWindow = new BrowserWindow({ 
  height: 620, 
  useContentSize: true, 
  width: 1280 ,
  frame: false /*去掉顶部导航 去掉关闭按钮 最大化最小化按钮*/
});

mainWindow.setMenu(null)

自定义最大,最小,关闭

const { ipcMain, BrowserWindow } = require("electron");
//window-min,window-max',window-close是渲染进程发送过来的自定义消息
ipcMain.on('window-min',function(){ mainWindow.minimize(); })//登录窗口最大化 
ipcMain.on('window-max',function(){ if(mainWindow.isMaximized()){ mainWindow.restore(); }else{mainWindow.maximize(); } })
ipcMain.on('window-close',function(){ mainWindow.close(); })

自定义可拖拽区域

可拖拽的 css: -webkit-app-region: drag; 
不可拖拽的 css: -webkit-app-region: no-drag;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容