[前端開發(fā)]PC桌面端-Electron學習筆記

Electron快速上手

基礎模板改造

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

腳手架工具開發(fā)

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

進程調度

Electron 中, 與 GUI 相關的模塊(如 dialog, menu 等)只存在于主進程,而不在渲染進程中 。 為了能從渲染進程中使用它們,需要用 ipc模塊來給主進程發(fā)送進程間消息。使用 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:當在主進程中使用時,它處理從渲染器進程(網頁)發(fā)送出來的異步和同步信息, 當然也有可能從主進程向渲染進程發(fā)送消息。
ipcRenderer: 使用它提供的一些方法從渲染進程 (web 頁面) 發(fā)送同步或異步的消息到主 進程。 也可以接收主進程回復的消息。

渲染進程給主進程發(fā)送異步消息:

const { ipcRenderer } = require('electron') ;
ipcRenderer.send('render2Main',{name:'steven'}); //渲染進程發(fā)送異步消息到主進程
ipcRenderer.on("main2render",(event,data)=>{
  console.log("主進程響應給渲染進程的數據",data);
})

//主進程監(jiān)聽渲染進程傳遞過來的數據,并發(fā)送消息給渲染進程
const { ipcMain } = require('electron'); 
ipcMain.on("render2Mainsg",(event,arg) => { 
console.log("渲染進程傳遞過來的數據",arg)
event.sender.send("main2render","主進程收到渲染進程發(fā)的異步消息")})

渲染進程給主進程發(fā)送同步消息

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

主進程通知渲染進程執(zhí)行操作

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

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

渲染進程和渲染進程之間通信

  • LocalStorage使數據兩個html頁面之間傳遞數據
  • 通過 BrowserWindow 和 webContents 模塊實現(xiàn)渲染進 程和渲染進程的通信
    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)=>{//渲染進程發(fā)出打開另一個窗口的事件: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"));
    //監(jiān)聽當前窗口加載完成的事件
    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 模塊可以在操作系統(tǒng)中注冊/注銷全局快捷鍵, 以便可以為操作定制各種快捷鍵

隱藏工具欄和自定義窗口操作區(qū)域

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是渲染進程發(fā)送過來的自定義消息
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(); })

自定義可拖拽區(qū)域

可拖拽的 css: -webkit-app-region: drag; 
不可拖拽的 css: -webkit-app-region: no-drag;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容