初学Electron(BrowserView、Net、Menu)

1,403 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

Menu模块

Menu模块可以在主进程中使用,如果要在渲染进程中使用需要借助IPC法送所需的信息到主过程,让主进程代替渲染进程渲染。 渲染进程使用Demo:

// renderer.js
window.addEventListener('contextmenu', (e) => {
  e.preventDefault()
  ipcRenderer.send('show-context-menu')//发送消息
})

ipcRenderer.on('context-menu-command', (e, command) => {
  // ...
})
// main.js
ipcMain.on('show-context-menu', (event) => {//接收消息并响应
  const template = [
    {
      label: 'Menu Item 1',
      click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
    },
    { type: 'separator' },
    { label: 'Menu Item 2', type: 'checkbox', checked: true }
  ]
  const menu = Menu.buildFromTemplate(template)
  menu.popup(BrowserWindow.fromWebContents(event.sender))
})

写一个menu菜单(主进程)

  • 引入所以对象
const { app, BrowserWindow,ipcMain,Menu, BrowserView,screen } = require('electron')
  • 在主进程ready函数后,创建主窗口后,编写
// 在主进程中直接使用menu模块
  const template = [
    {
      label: '菜单1',
      submenu: [
        {label: '1.1页面' },
        { label: '1.2页面' },
        { label: '1.3页面' },
        { label: '1.4页面' },
      ]
    },
    {
      label: '菜单2',
      submenu: [
        { label: '2.1页面' },
        { label: '2.2页面' },
        { label: '2.3页面' },
        { label: '2.4页面' },
      ]
    }
  ]
  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
  • 效果如下

1.gif

BrowserView模块

接续上面的案例,我们来实现点击1.1页面和2.1页面对应不能通窗口效果,如下:

2.gif

点击菜单具有响应的BrowserView

------------省略-------------------
 const template = [
    {
      label: '菜单1',
      submenu: [
        {
          label: '1.1页面',
          click: () => {
            const view = new BrowserView()
            win.setBrowserView(view)
            view.setBounds({ x: 0, y: 0, width: 800, height: 600 })
            // view.setAutoResize({width:true,height:true})
            //据说设置这个可以让窗口自适应,但是我发现并没有效果,如有大佬知道怎么回事儿,还请指点指点❤
         view.webContents.loadURL(`file://${__dirname}/page/page1.1.html`)
          }
        },
        { label: '1.2页面' },
        { label: '1.3页面' },
        { label: '1.4页面' },
      ]
    },
    {
      label: '菜单2',
      submenu: [
        { label: '2.1页面' ,
        click: () => {
          const view = new BrowserView()
          win.setBrowserView(view)
          view.setBounds({ x: 0, y: 0, width: 800, height: 600 })
          view.webContents.loadURL(`file://${__dirname}/page/page2.1.html`)
        }},
        { label: '2.2页面' },
        { label: '2.3页面' },
        { label: '2.4页面' },
      ]
    }
  ]
-------------省略------------------

Net模块

请求一个Cnode文章的内容

  • 引入net模块
//首先引入remote
const remote = require('@electron/remote')
//人后引入net模块
const net = remote.require('electron').net;
  • 调用Request方法
//请求api地址
const request = net.request('https://cnodejs.org/api/v1/topic/5433d5e4e737cbe96dcef312');
      request.on('response',
       (response) => {
        console.log(`**statusCode:${response.statusCode}`);//状态码
        console.log(response.headers);//请求头
         response.on("data", (chunk) => {
             console.log("接收到数据:", JSON.parse(chunk.toString()).data);//数据
         response.on('end', () => {
          console.log("数据接收完成");//当数据非常多的时候会打印,数据少的时候没有打印,也不知道是什么原因,有大佬知道可以指正
        })
      });
      //结束请求,不然没有响应数据
      request.end()