搭建electron+vue項(xiàng)目

前言

Electron是一個(gè)使用 JavaScript万搔、HTML 和 CSS 構(gòu)建桌面應(yīng)用程序的框架跟继。 嵌入 ChromiumNode.js 到 二進(jìn)制的 Electron 允許您保持一個(gè) JavaScript 代碼代碼庫(kù)并創(chuàng)建 在Windows上運(yùn)行的跨平臺(tái)應(yīng)用 macOS和Linux——不需要本地開(kāi)發(fā) 經(jīng)驗(yàn)柄沮。
electron搭建了一個(gè)殼,集成了chromium和node環(huán)境,業(yè)務(wù)邏輯只需要按vue寫(xiě)法即可。

方式一

直接使用electron-vue邻吭,具體內(nèi)容見(jiàn)文檔,優(yōu)點(diǎn)是配置齊全宴霸,即開(kāi)即用囱晴。缺點(diǎn)是很多配置已經(jīng)固定,比如eslint瓢谢,如果跟自己的開(kāi)發(fā)習(xí)慣不匹配的話畸写,需要做調(diào)整,另外electron的版本比較老氓扛。

方式二

vue-cli + electron艺糜,目前是我采用的方式。

搭建vue項(xiàng)目

此處不多做介紹幢尚,直接看文檔,我使用的是vite+vue3翅楼,有需要的可以去看文檔

安裝electron
npm i -D electron
配置electron入口

新建electron文件夾

image.png

代碼結(jié)構(gòu)如圖

// main.js
const { app, BrowserWindow } = require('electron');
const getMenuPersonal = require('./menu');
const getWindow = require('./window');

app.whenReady().then(() => {
    let win = new getWindow().createWindow(); //創(chuàng)建窗口
    new getMenuPersonal(win).createMenu(); //創(chuàng)建工具欄
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});
app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) new getWindow().createWindow();
});


// window.js
const windowStateKeeper = require('electron-window-state');
const path = require('path');
const { Menu, BrowserWindow, Tray, app } = require('electron');
const { join } = require('path');

process.env.DIST = join(__dirname, '../../');
const indexHtml = join(process.env.DIST, 'dist/index.html');
/**
 * 創(chuàng)建窗口對(duì)象*/
class Window {
    win = null;

    getWindowState() {
        // 配置electron-window-state插件,獲取窗口option
        let win;
        const mainWindowState = windowStateKeeper({
            defaultWidth: 1000,
            defaultHeight: 800
        });
        let { width, height } = mainWindowState;
        const options = {
            width,
            height,
            devTools: true,
            show: false,
            // icon: path.resolve(__dirname, '../log.ico'),
            webPreferences: {
                // nodeIntegration:true,  //集成node api
                // contextIsolation:false  //關(guān)閉上下文隔離尉剩,配合nodeIntegration,可以賦予在render進(jìn)程中寫(xiě)node代碼的能力
                preload: path.resolve(__dirname, '../preload/preload.js') //預(yù)加載的js文件
                // webSecurity: false, // 同源策略
            }
        };

        win = new BrowserWindow(options);
        mainWindowState.manage(win);

        return win;
    }

    createContextMenu(contents) {
        //    創(chuàng)建右鍵菜單
        let contextMenu = Menu.buildFromTemplate([{ label: 'Item 1' }, { role: 'editMenu' }]);
        contents.on('context-menu', (e, params) => {
            contextMenu.popup();
        });
    }

    createTray() {
        // 創(chuàng)建托盤(pán)
        let trayMenu = Menu.buildFromTemplate([{ label: 'Item 1' }, { role: 'quit' }]);
        let tray = new Tray(path.resolve(__dirname, '../trayTemplate.png'));
        tray.setToolTip('Tray details');
        tray.on('click', e => {
            console.log(e);
            if (e.shiftKey) {
                app.quit();
            } else {
                this.win.isVisible() ? this.win.hide() : this.win.show();
            }
        });
        tray.setContextMenu(trayMenu);
    }

    async createWindow() {
        this.win = this.getWindowState();
        this.createTray();

        if (app.isPackaged) {
            this.win.loadFile(indexHtml);
            // this.win.loadURL(' https://www.baidu.com/');
        } else {
            this.win.loadURL('http://localhost:3004');
        }
        //等待dom渲染后打開(kāi)窗口
        this.win.on('ready-to-show', () => {
            this.win.show();
        });
        this.win.on('closed', () => {
            this.win = null;
        });

        let contents = this.win.webContents;

        contents.openDevTools();

        // 開(kāi)啟vue-devtools
        // await session.defaultSession.loadExtension(path.join(__dirname, '../../node_modules/vue-devtools/vender'));

        this.createContextMenu(contents);
        this.createTray();

        return this.win;
    }
}

module.exports = Window;

創(chuàng)建窗口需要添加依賴 electron-window-state

npm i electron-window-state
修改配置package.json
  • 由于electron使用node模塊毅臊,需要修改"type": "commonjs"
  • 配置electron入口 "main": "electron/main/main.js"
  • 添加啟動(dòng)script "start": "electron --inspect=3004 ."
啟動(dòng)

先啟動(dòng)vue項(xiàng)目

npm run dev

然后啟動(dòng)electron

npm run start

到此理茎,基礎(chǔ)配置已經(jīng)完成。

問(wèn)題

  1. 安裝electron的過(guò)程當(dāng)中管嬉,有可能會(huì)出現(xiàn)下載失敗皂林,這種情況寫(xiě)可以配置npm源地址,具體內(nèi)容見(jiàn)文檔
  2. 生成托盤(pán)的圖片加載失敗 Failed to load image from path ?xxx蚯撩,此種情況是圖片格式不對(duì)础倍,可以去iconfont里去下載,尺寸選16即可
    image.png
  3. 使用vue-devtools胎挎,由于較新版本的electron中BrowserWindow.addDevToolsExtension接口已經(jīng)廢棄沟启,因此網(wǎng)上有些回答BrowserWindow.addDevToolsExtension(xxx)會(huì)報(bào)錯(cuò)TypeError: electron.BrowserWindow.addDevToolsExtension is not a function忆家,官網(wǎng)有提供替換接口session.loadExtension(path),可以將vue-devtools下載到本地引入德迹。
    我這里使用了@vue/devtools
// 安裝 
npm i -D @vue/devtools

// 使用
./node_modules/.bin/vue-devtools
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芽卿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胳搞,更是在濱河造成了極大的恐慌卸例,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肌毅,死亡現(xiàn)場(chǎng)離奇詭異筷转,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)芽腾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)旦装,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人摊滔,你說(shuō)我怎么就攤上這事阴绢。” “怎么了艰躺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵呻袭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我腺兴,道長(zhǎng)左电,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任页响,我火速辦了婚禮篓足,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闰蚕。我一直安慰自己栈拖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布没陡。 她就那樣靜靜地躺著涩哟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盼玄。 梳的紋絲不亂的頭發(fā)上贴彼,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音埃儿,去河邊找鬼器仗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛童番,可吹牛的內(nèi)容都是我干的青灼。 我是一名探鬼主播暴心,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼杂拨!你這毒婦竟也來(lái)了专普?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤弹沽,失蹤者是張志新(化名)和其女友劉穎檀夹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體策橘,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炸渡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丽已。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚌堵。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沛婴,靈堂內(nèi)的尸體忽然破棺而出吼畏,到底是詐尸還是另有隱情,我是刑警寧澤嘁灯,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布泻蚊,位于F島的核電站,受9級(jí)特大地震影響丑婿,放射性物質(zhì)發(fā)生泄漏性雄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一羹奉、第九天 我趴在偏房一處隱蔽的房頂上張望秒旋。 院中可真熱鬧,春花似錦诀拭、人聲如沸迁筛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至铺然,卻和暖如春俗孝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背魄健。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工赋铝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沽瘦。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓革骨,卻偏偏與公主長(zhǎng)得像农尖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子良哲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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