electron 如何外包电子菜单代码从main.js到单独的menu.js?

jmo0nnb3  于 2023-03-16  发布在  Electron
关注(0)|答案(1)|浏览(198)

我的main.js中的电子菜单代码现在很长。是否可以将其外包给另一个文件?如果可以,我是否仍然可以从菜单中调用位于main.js中的函数?

// MENU BEGIN
/////////////////////////////////////////////////////////////////////
const { app, Menu } = require('electron')

const isMac = process.platform === 'darwin'
const isWin = process.platform === 'win32'

const template = [
    // { role: 'appMenu' }
    ...(isMac ? [{
        label: app.name,
        submenu: [
            { role: 'about' },
            { type: 'separator' },
            { role: 'services' },
            { type: 'separator' },
            { role: 'hide' },
            { role: 'hideOthers' },
            { role: 'unhide' },
            { type: 'separator' },
            { role: 'quit' }
        ]
    }] : []),
    // more menu code...
    {
        role: 'help',
        submenu: [
            {
                label: 'Learn More',
                click: async () => {
                    const { shell } = require('electron')
                    await shell.openExternal('https://github.com/aronsommer/eddy-g')
                }
            }
        ]
    }
]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
/////////////////////////////////////////////////////////////////////
// MENU END
n9vozmp4

n9vozmp41#

随着你的电子应用程序的增长,你必须开始把你的代码分离到它们自己的文件中。这就是所谓的分离你的关注点。它使一个整洁,易于阅读结构良好的项目。
将菜单的创建从main.js文件分离到它自己的文件中(我们称之为menu.js),然后导出它的build()函数。
menu.js(主线程)

// Import the necessary Electron modules
const electronApp = require('electron').app;
const electronMenu = require('electron').Menu;

const isMac = process.platform === 'darwin'
const isWin = process.platform === 'win32'

function build() {
    const template = [
        // { role: 'appMenu' }
        ...(isMac ? [{
            label: electronApp.name,
            submenu: [
                { role: 'about' },
                { type: 'separator' },
                { role: 'services' },
                { type: 'separator' },
                { role: 'hide' },
                { role: 'hideOthers' },
                { role: 'unhide' },
                { type: 'separator' },
                { role: 'quit' }
            ]
        }] : []),
        // more menu code...
        {
            role: 'help',
            submenu: [
                {
                    label: 'Learn More',
                    click: async () => {
                        const { shell } = require('electron')
                        await shell.openExternal('https://github.com/aronsommer/eddy-g')
                    }
                }
            ]
        }
    ];
    
    electronMenu.setApplicationMenu(electronMenu.buildFromTemplate(template));
}

// Export the publicly available function
module.exports = {build};

现在,在您的main.js文件中,像处理任何其他文件一样请求它,然后在应用程序为ready时调用build()函数。
注意:我已经从createWindow()函数中调用了菜单build()函数,因为它实际上是窗口创建的一部分。菜单是窗口的一部分。
main.js(主线程)

const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;

const nodePath = require("path");

const appMenu = require('menu');

let window;

function createWindow() {
    const window = new electronBrowserWindow({
        x: 0,
        y: 0,
        width: 800,
        height: 600,
        show: false,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            preload: nodePath.join(__dirname, 'preload.js')
        }
    });

    window.loadFile('index.html')
        .then(() => { appMenu.build(); } // Build the menu
        .then(() => { window.show(); });

    return window;
}

electronApp.on('ready', () => {
    window = createWindow();
});

electronApp.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        electronApp.quit();
    }
});

electronApp.on('activate', () => {
    if (electronBrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});

关于您的问题“我还能从菜单中调用位于main.js中的函数吗?"。
答案是肯定的,如果你require那些函数在你的menu.js文件的顶部。
如果你不想从你的menu.js文件中require所有这些函数,你可以要求节点的事件模块和菜单clickemit一个事件和监听它在你的其他脚本(s).这种设计允许一个非常模块化的应用程序,允许新功能添加在以后没有任何困难.

奖金

在单独的文件中构建菜单还允许您在任何菜单项需要更改时动态更新(重新构建)菜单。
menu.js(主线程)

// Rebuild the menu on localisation change.
appEvents.on('locale:changed', () => {
    appMenu.build();
});

相关问题