用electron將vue.js項(xiàng)目改造成桌面應(yīng)用

關(guān)于Electron

Electron是由Github開(kāi)發(fā),用HTML,CSS和JavaScript來(lái)構(gòu)建跨平臺(tái)桌面應(yīng)用程序的一個(gè)開(kāi)源庫(kù)。
Electron通過(guò)將Chromium和Node.js合并到同一個(gè)運(yùn)行時(shí)環(huán)境中,并將其打包為Mac,Windows和Linux系統(tǒng)下的應(yīng)用來(lái)實(shí)現(xiàn)這一目的。

按我的理解,就是用讓你用 JavaScript 代碼去操作系統(tǒng)的API,達(dá)到與原生應(yīng)用相似的體驗(yàn),當(dāng)然GUI則是一個(gè)web界面,簡(jiǎn)而言之就是個(gè)chrome內(nèi)核的瀏覽器。

Electron用法

Electron Application使用 JavaScript 開(kāi)發(fā),工作原理與方法與 node.js 相同,引入 electron 模塊,包含了 Electron 提供的所有API和功能。

electron官方文檔

項(xiàng)目需求

為我們web端服務(wù)做的前期demo,功能上很簡(jiǎn)單,APP顯示我們的web站點(diǎn),當(dāng)即時(shí)通訊有消息送達(dá)時(shí),系統(tǒng)托盤(pán)需要閃爍,右鍵點(diǎn)擊系統(tǒng)托盤(pán)需要有如下功能

功能實(shí)現(xiàn)

app顯示web站點(diǎn)

引入 electron 模塊,使用 BrowserWindow 類渲染窗口。

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

//創(chuàng)建主頁(yè)面
function createWindow() {

    mainWindow = new BrowserWindow({
        show: false,
        autoHideMenuBar: true,
        title: 'ElectronApp'
    })
    //最大化
    mainWindow.maximize();
    // 然后加載應(yīng)用的 index.html。
    mainWindow.loadFile('./app/index.html');
    //窗口關(guān)閉時(shí)觸發(fā)
    mainWindow.on('closed', () => {
        mainWindow = null
    });
    //打開(kāi)開(kāi)發(fā)者工具
    mainWindow.webContents.openDevTools();
    //渲染完成后
    mainWindow.on('ready-to-show', function () {
        //顯示窗口
        mainWindow.show();
        //頁(yè)面聚焦
        mainWindow.focus();
    });

}

這里加載html方法有兩種:

1.使用 loadURL('https://electronjs.org') 直接指向某個(gè)地址。

2.使用 loadFile('./app/index.html') 指向html文件,在index頁(yè)面中,使用 <webview> 標(biāo)簽加載 url 地址。

在實(shí)際使用中,第一種適配我們項(xiàng)目時(shí)有bug,推薦使用第二種加載方式。

系統(tǒng)配置

在 electron 模塊中引入,globalShortcut(全局快捷鍵),Menu(菜單),Tray(托盤(pán)),ipcMain(異步通信),shell(系統(tǒng)命令)。

const {app, BrowserWindow, globalShortcut, Menu, Tray, ipcMain, shell} = require('electron')


let tray
//托盤(pán)右鍵菜單
let template = [
    {
        label: '訪問(wèn)地址、快捷鍵、開(kāi)機(jī)啟動(dòng)設(shè)置', click: function () {
            createConfig();
        }
    },
    {
        label: '打開(kāi)主界面', click: function () {
            mainWindow.show();
        }
    },
    {
        label: '即時(shí)通訊'
    },
    {
        label: '使用系統(tǒng)瀏覽器打開(kāi)web站點(diǎn)', click: function () {
            shell.openExternal(configuration.readSettings('global_url'));
        }
    },
    {
        label: "退出", role: 'quit'
    }
];

app.on('ready', () => {
    //創(chuàng)建窗口
    createWindow();
    //系統(tǒng)托盤(pán)
    tray = new Tray('./app/img/app-icon.ico');
    //設(shè)置此托盤(pán)圖標(biāo)的懸停提示內(nèi)容
    tray.setToolTip('中科天翔');
    const contextMenu = Menu.buildFromTemplate(template);
    tray.setContextMenu(contextMenu);
    tray.on("click", function () {
        //閃爍時(shí)點(diǎn)擊彈出即時(shí)通訊頁(yè)面
        if (flashTrayTimer) {
            mainWindow.show();
            //顯示即時(shí)通訊
            mainWindow.webContents.send('ping', 'openMessage');
            //停止閃爍
            flashTray(false);
            tray.setImage('./app/img/app-icon.ico')
        } else {
            //主窗口顯示隱藏切換
            mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
        }
    })
    //設(shè)置默認(rèn)配置參數(shù)
    setBootStart();
    //設(shè)置全局快捷鍵
    setGlobalShortcuts();
})

即時(shí)通訊閃爍圖標(biāo)

整體思路大概是這樣的,通過(guò)事件監(jiān)聽(tīng)cookie變化,web端即時(shí)通訊收到消息以后,將 cookie 值變?yōu)?new ,觸發(fā)異步通信 ipcRenderer 發(fā)送消息,ipcMain 監(jiān)聽(tīng)消息 ,觸發(fā)函數(shù)開(kāi)始閃爍圖標(biāo)(就是將圖標(biāo)與空白圖標(biāo)來(lái)回切換),當(dāng)然打開(kāi)托盤(pán)即時(shí)通訊也有類似操作。

//收到消息
webview.addEventListener('dom-ready', () => {
    var currCookies = webview.getWebContents().session.cookies;
    webview.getWebContents().openDevTools();
    //監(jiān)聽(tīng)cookie
    currCookies.addListener('changed', (event, cookie, cause, removed) => {
        //客戶端打開(kāi)即時(shí)通訊
        if (cookie.name == 'electron' && cookie.value == 'open') {
            ipcRenderer.send('open-message');
        }
        //有新消息提醒閃爍
        if (cookie.name == 'electron' && cookie.value == 'new') {
            ipcRenderer.send('receive-message');
        }
    });

})


//即時(shí)通訊
ipcMain.on('receive-message', function () {
    //先關(guān)閉再閃爍
    flashTray(false);
    tray.setImage('./app/img/app-icon.ico');
    flashTray(true);
});

ipcMain.on('open-message', function () {
    //關(guān)閉托盤(pán)閃爍
    flashTray(false);
    tray.setImage('./app/img/app-icon.ico');
});

修改配置

修改配置思路比較簡(jiǎn)單,通過(guò) nconf 模塊,將配置保存在本地,app初始化的時(shí)候讀取配置。

喚醒/隱藏界面快捷鍵

在配置界面的html中,將喚醒/隱藏界面的 input 標(biāo)簽加上 onkeydown 事件,來(lái)監(jiān)聽(tīng)用戶鍵盤(pán)按鍵操作,保存時(shí)寫(xiě)入配置文件。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容