Electron笔记

这篇具有很好参考价值的文章主要介绍了Electron笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基础环境搭建

官网:https://www.electronjs.org/zh/

这一套笔记根据这套视频而写的

创建项目

方式一:

官网点击GitHub往下拉找到快速入门就能看到下面这几个命令了

git clone https://github.com/electron/electron-quick-start  //克隆项目
cd electron-quick-start  //切换到项目目录
npm install //这里可能会有报错问题,本人查了gpt说是什么连接远程失败,这里本人建议使用cnpm淘宝镜像,没有的可以百度安装一下,yarn也不行(亲测yarn安装还是报错)
npm start //启动项目

目录结构

Electron笔记,electron,electron,笔记,arcgis

方式二:

先安装

cnpm install --save-dev electron   //这里也是建议使用cnpm淘宝镜像

直接使用npm或者yarn都可能会报错,官方也有解释,这里本人使用cnpm就没问题

Electron笔记,electron,electron,笔记,arcgis

然后在package.json里面创建如下内容

{
  "name": "my-electron-app",
  "version": "1.0.0",
  "description": "Hello World!",
  "main": "main.js", //这里是主入口
  "author": "萧寂",
  "license": "MIT",
  "scripts": {
    "start": "electron ." //运行的命令
  },
  "devDependencies": {
    "electron": "^26.0.0"
  }
}

如果安装了nodemon,可以在script节点进行如下配置,可以监听js的代码并实时变化
在html代码改变后不会立即监听,需要切换到应用里面按下CTRL+R即可刷新

"scripts": {
  "start": "nodemon --watch main.js --exec npm run build",
  "build": "electron ."
},

在同级创建main.js,然后在main.js中插入以下内容

const { app, BrowserWindow } = require("electron");
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    width: 800,
    height: 600,
  });
  //当前窗口显示的页面
  win.loadFile("index.html");
};

// app启动之后创建窗口
app.on("ready", () => {
  console.log("窗口加载");
  createWindow();
});

// 生命周期
// 通过on监听事件

// 监听关闭的
app.on("close", () => {
  console.log("当前窗口关闭");
});

app.on("window-all-closed", () => {
  console.log("所有窗口关闭");
  //退出应用
  app.quit();
});

CTRL+SHIFT+I可以打开调试面板
同级下创建index.html文件

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP -->
    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'self'"
    />
    <title>萧寂</title>
  </head>
  <body>
    <h1>你好!</h1>
    我们正在使用 Node.js <span id="node-version"></span>, Chromium
    <span id="chrome-version"></span>, 和 Electron
    <span id="electron-version"></span>.
  </body>
</html>

然后直接运行

npm start

目录结构

Electron笔记,electron,electron,笔记,arcgis

因为第二种方式目录结构简单,所以在这里演示的所有代码都以第二种创建方式基础上写的

electron生命周期事件

ready:app初始化完成  //重要
dom-ready:一个窗口中的文本加载完成  //重要
did-finsh-load:导航完成时触发   //重要
window-all-closed:所有窗口都被关闭时触发  //重要
before-quit:在关闭窗口之前触发
will-quit:在窗口关闭并且应用退出时触发
quit:当所有窗口被关闭时触发
close:当窗口关闭时触发,此时应删除窗口引用

main.js代码

const { app, BrowserWindow } = require("electron")
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    width: 800,
    height: 600,
  })
  //当前窗口显示的页面
  win.loadFile("index.html")

  // 这个webContents对象可以控制dom元素加载事件
  win.webContents.on('did-finish-load', () => {
    console.log('3333->did-finish-load')
  })
  win.webContents.on('dom-ready', () => {
    console.log('2222->dom-ready')
  })
  // 窗口关闭
  win.on('close', () => {
    console.log('8888->close')
    // 从性能考虑,应该释放窗体这个变量,删除窗体引用
    win = null
  })
}

// 生命周期
// 通过on监听事件
app.on('ready', () => {
  console.log("1111->ready")
  createWindow()
})

app.on("window-all-closed", () => {
  // 如果监听了window-all-closed这个事件,需要在事件里面主动退出应用,没有监听事件的话默认会直接退出应用
  // 但如果监听了此事件,但没有退出操作的话,后续的567生命周期也不会执行
  console.log("4444->window-all-closed")
  //退出应用
  app.quit()
})

app.on("before-quit", () => {
  console.log("5555->before-quit")
})

app.on("will-quit", () => {
  console.log("6666->will-quit")
})

app.on("quit", () => {
  console.log("7777->quit")
})

从打开窗体到关闭窗体打印结果如下

Electron笔记,electron,electron,笔记,arcgis

创建窗体时所携带的一些属性

也是main.js代码

const { app, BrowserWindow } = require("electron")
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100, 
    y: 50, //窗体坐标
    show: false, //不展示窗体
    width: 800,
    height: 600, //长宽
    maxHeight: 600,
    maxWidth: 1000, //最大宽高
    minHeight: 200,
    minWidth: 300, //最小宽高
    resizable: false, //不允许缩放
    title: "萧寂", //标题(加上这个属性,在页面中就不要有title标签了)
    icon: "./及格.png", //设置icon图标
    // frame: false, //只保留主体部分,不保留其他的选项卡窗口了,隐藏菜单栏
    // transparent: true, //将窗体完全透明化
    autoHideMenuBar: true, //只保留标题,不保留其他的选项卡部分
  })

  // show需要设置false,意思就是默认不显示窗体,然后执行下面这个事件,ready-to-show:等待完毕准备加载执行,适用于页面显示,监听到了再执行show()
  win.on('ready-to-show', () => {
    win.show()
  })
  //当前窗口显示的页面
  win.loadFile("index.html")
  // 窗口关闭
  win.on('close', () => {
    console.log('close')
    win = null
  })
}

// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

窗口标题及环境(创建窗口)

这里要说明一下,低版本直接可以使用一个remote,主进程稍微配置一下就能创建窗口了,高版本就不行了,高版本需要安装一个@electron/remote模块,通过对这个模块稍微配置一下也能创建窗口了,本人之前版本是"electron": "^26.0.0","@electron/remote": "^2.0.11",[具体配置可以可以看看这个小哥的博客](https://blog.csdn.net/qq_39077394/article/details/125667918?ops_request_misc=%7B%22request%5Fid%22%3A%22169651971016800213043799%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=169651971016800213043799&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-125667918-null-null.142v94insert_down28v1&utm_term=enableRemoteModule%3A true不能使用remote&spm=1018.2226.3001.4187),我下面的代码和这两个不一样我是在主进程创建窗口,渲染进程向主进程发请求才能创建窗体(下面代码示例就是这个方法),因为方式和另两种不一样,因此记录一下

ctrl+r 可以刷新当前窗口的index.html样式,ctrl+shift+i可以打开调试窗口

这里强调一下main.js为主进程,创建的js里面重新创建的窗口为渲染进程

主进程main.js代码如下

const { app, BrowserWindow, ipcMain } = require("electron") // ipcMain用于渲染进程创建窗体使用
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100,
    y: 50, //窗体坐标 
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,  //加入这两行代码就可以正常使用require了,不会报错了
    }
  })
  //当前窗口显示的页面
  win.loadFile("index.html")
  // 窗口关闭
  win.on('close', () => {
    console.log('close')
    win = null
  })
}
// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

// 下面代码就是创建渲染进程窗体代码
// 在主进程中监听渲染进程的请求
// open-window后面的回调函数,参数一默认是事件对象,参数二为渲染进程传递来的数据
// pageFileName为ipcRenderer.send()的第二个参数,ipcRenderer.send()由渲染进程发起,参数一为事件名,参数二为页面配置(大小,位置等等)
ipcMain.on('open-window', (event, winconfig) => {
  console.log('winconfig', winconfig)
  // 创建新窗口并设置相应的配置(配置由渲染进程提供)
  let newWindow = new BrowserWindow(winconfig)
  // 这里设置的是winconfig.pageFileName,所以渲染进程的请求的配置中必须pageFileName代表页面
  newWindow.loadFile(winconfig.pageFileName)
  // 监听创建的窗体关闭事件
  newWindow.on('close', () => {
    console.log('close')
    newWindow = null
  })
})

主进程页面index.html代码

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <!-- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
  <title>萧寂</title>
</head>

<body>
  <h1>窗口标题</h1>
  <button id="btn">打开第一个新窗口</button>
  <button id="btn2">打开第二个新窗口</button>
  <!-- 这里必须要使用外联,不能直接在下面写,不然会报错,大概意思就是不能使用内联脚本 -->
  <script src="./index.js"></script>
</body>
</html>

渲染进程index.js代码

// 这里强调一下main.js为主进程,窗口里面页面点击创建的js里面重新创建的窗口为渲染进程
// require直接使用会报错,因为electron是不被允许直接require的,不给这个权限,需要我们自行放开
// 权限需要在窗口的配置定义webPreferences对象,值为 {nodeIntegration: true,contextIsolation: false},这样就可以正常使用require了

// 创建窗口这里使用的是electron自带的ipcRenderer属性,它是向主进程发送创建窗体请求,参数一为事件名,参数二为窗体配置
const { ipcRenderer } = require("electron")
const path = require("path")
window.addEventListener("DOMContentLoaded", () => {
  // 点击按钮打开新窗口
  // 获取btn
  const btn = document.getElementById("btn")
  // 按钮点击打开新窗口
  btn.addEventListener("click", () => {
    // 创建新窗口(向主进程发起请求,创建窗体,并显示pageFileName指定的页面)
    ipcRenderer.send('open-window', {
      width: 600,
      height: 400,
      webPreferences: {
        nodeIntegration: true,
        contextIsolation: false
      },
      pageFileName: path.join(__dirname, "list.html") // 确保传递了正确的页面文件名,list.html需要显示的页面
    })
  })


  // 打开第二个窗口
  // 获取btn
  const btn2 = document.getElementById("btn2")
  // 按钮点击打开新窗口
  btn2.addEventListener("click", () => {
    // 创建新窗口(向主进程发起请求,创建窗体,并显示pageFileName指定的页面)
    ipcRenderer.send('open-window', {
      width: 200,
      height: 200,
      webPreferences: {
        nodeIntegration: true,
        contextIsolation: false
      },
      pageFileName: path.join(__dirname, "list2.html") // 确保传递了正确的页面文件名,list2.html需要显示的页面
    })
  })
})

项目结构

Electron笔记,electron,electron,笔记,arcgis

效果图

Electron笔记,electron,electron,笔记,arcgis

自定义窗口的实现(以及阻止窗口关闭)

项目结构

Electron笔记,electron,electron,笔记,arcgis

安装

npm install --save @electron/remote

main.js代码如下

const { app, BrowserWindow } = require("electron")
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100,
    y: 50, //窗体坐标 
    frame: false, // 只保留主体部分,然后后面的样式全部都是由html去模拟
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,  //加入这两行代码就可以正常使用require了,不会报错了
      enableRemoteModule: true
    }
  })
  require('@electron/remote/main').initialize()
  require("@electron/remote/main").enable(win.webContents)

  //当前窗口显示的页面
  win.loadFile("index.html")
  // 窗口关闭
  win.on('close', () => {
    console.log('close')
    win = null
  })
}


// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

index.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <!-- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
  <title>萧寂</title>
  <link rel="stylesheet" href="./index.css">
</head>

<body>
  <main>
    <h1 class="box">主题内容</h1>
    <div>
      <span></span>
      <span></span>
      <span>X</span>
    </div>
  </main>
  <h2>上面的三个模拟最小化,最大化和关闭</h2>

  <div class="isShow">
    <h3>是否关闭当前应用</h3>
    <p>系统可能不会保存您的所有更改</p>
    <p><span class="s1"></span><span class="s1"></span></p>
  </div>
  <script src="./index.js"></script>
</body>

</html>

index.css

main {
  display: flex;
  justify-content: space-evenly;
  align-items: center;
}
.box {
  color: red;
}
span {
  padding: 10px 5px;
  cursor: pointer;
}
/* 将提示语隐藏 */
.isShow {
  display: none;
}
.s1 {
  cursor: pointer;
}

index.js

const remote = require("@electron/remote")

window.addEventListener('DOMContentLoaded', () => {
//利用remote获取当前窗口对象
  let mainwin = remote.getCurrentWindow()
  
  // 这里代码是当窗口关闭,去进行一下阻止,并弹出提示框,用户确定关闭再进行关闭
  // 监听close事件,close事件触发会执行这个事件onbeforeunload
  window.onbeforeunload = function () {
    // 获取到弹框dom元素,并设置样式
    document.querySelector('.isShow').style.display = 'block'
    // 将主题内容隐藏
    document.querySelector('h2').style.display = 'none'

    // 获取弹窗的按钮(确认和取消)
    let btn = document.querySelectorAll('.s1')

    // 点击确认关闭按钮
    btn[0].addEventListener('click', () => {
      // 这里不再使用close事件,不然会一直触发window.onbeforeunload事件,进入死循环了
      mainwin.destroy() //窗口销毁
    })

    // 点击取消按钮
    btn[1].addEventListener('click', () => {
      // 将窗口隐藏就好了
      // 获取到弹框dom元素,并设置样式
      document.querySelector('.isShow').style.display = 'none'
      // 将主题内容显示
      document.querySelector('h2').style.display = 'block'
    })
    return false
  }

  const spans = document.querySelectorAll('span')

  // 最小化
  spans[0].addEventListener("click", () => {
    mainwin.minimize() //窗口最小化
  })
  // 放大
  spans[1].addEventListener("click", () => {
    // 最大化操作
    console.log('mainwin.isMaximized()', mainwin.isMaximized())  //false,返回布尔值,代表当前界面是否是最大化了
    if (!mainwin.isMaximized()) {
      mainwin.maximize() //如果没有最大化的话,给个最大化
    } else {
      mainwin.restore() //如果是最大化了,给它恢复到初始状态
    }
  })
  // 关闭窗口
  spans[2].addEventListener("click", () => {
    mainwin.close()  //关闭窗口
  })
})

效果图

Electron笔记,electron,electron,笔记,arcgis

当点击关闭按钮,会弹出提示框,点击是就关闭,点击否会将提示框进行隐藏
Electron笔记,electron,electron,笔记,arcgis

父子及模态窗口

模态窗口定义:定义完以后不能对主窗口或者别的窗口进行操作,除非模态窗口
其余代码和上面一样,只修改了index.js代码,代码如下

const remote = require('@electron/remote')

window.addEventListener('DOMContentLoaded', () => {
  let btn = document.querySelector('#btn')
  btn.addEventListener('click', () => {
    let subWin = new remote.BrowserWindow({
      width: 200,
      height: 200,
      parent: remote.getCurrentWindow(), //这个属性指向父级,实现了父子关联
      modal: true,  //定义模态窗口(默认为false,定义完以后不能对主窗口或者别的窗口进行操作,除非关闭模态窗口)
    })
    subWin.loadFile('sub.html')
    subWin.on('close', () => {
      subWin = null
    })
  })
})

自定义菜单

main.js代码如下

const { app, BrowserWindow, Menu } = require("electron") //Menu是菜单模块

console.log(process.platform)

const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100,
    y: 50,
    title: '自定义菜单',
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true,
    }
  })

  // 1.这里定义菜单(定义自己需要的菜单项)
  let menuTemp = [
    {
      label: '文件',
      submenu: [ //定义二级菜单
        {
          label: '打开文件',
          click () {
            // 这里就可以使用每个选项的点击事件
            console.log('当前需要的就是打开某一具体的文件')
          }
        },
        {
          type: 'separator'  // 添加分割线,就这一个属性将上下分隔开
        },
        {
          label: '关闭文件夹'
        },
        {
          label: '关于',
          role: 'about' //弹出关于项
        }
      ]
    },
    {
      label: '编辑'
    }
  ]
  // 2.利用上面菜单项生成一个菜单
  let menu = Menu.buildFromTemplate(menuTemp)
  // 3.将上述的自定义菜单添加到应用里面
  Menu.setApplicationMenu(menu)

  require('@electron/remote/main').initialize()
  require("@electron/remote/main").enable(win.webContents)
  win.loadFile("index.html")
  win.on('close', () => {
    console.log('close')
    win = null
  })
}


// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

这里打印有点中文乱码问题,解决方法就是在终端输入chcp 65001回车,重新执行即可解决中文乱码问题

菜单角色及类型

main.js代码

const { app, BrowserWindow, Menu } = require("electron")
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100,
    y: 50, //窗体坐标 
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,  //加入这两行代码就可以正常使用require了,不会报错了
      enableRemoteModule: true
    }
  })
  require('@electron/remote/main').initialize()
  require("@electron/remote/main").enable(win.webContents)

  //  1.自定义菜单项
  let menutap = [
    {
      label: '角色',
      submenu: [
        { label: '复制', role: 'copy' },
        { label: '剪切', role: 'cut' },
        { label: '粘贴', role: 'paste' },
        { label: '最小化', role: 'minimize' },
      ]
    },
    {
      label: '类型',
      submenu: [
        { label: '多选一', type: 'checkbox' },
        { label: '多选二', type: 'checkbox' },
        { label: '多选三', type: 'checkbox' },
        { type: 'separator' },
        { label: '单选1', type: 'radio' },
        { label: '单选2', type: 'radio' },
        { label: '单选3', type: 'radio' },
        { type: 'separator' },
        { label: 'windows', type: 'submenu', role: 'windowMenu' } //这里两个属性必须同时给出
      ]
    },
    {
      label: '其他',
      submenu: [
        {
          label: '打开',
          icon: '',
          accelerator: 'ctrl + o', //定义快捷键
          click () {
            console.log('打开操作执行了')
          }
        }
      ]
    }
  ]
  // 2.依据上述的数据创建一个menu
  let menu = Menu.buildFromTemplate(menutap)
  // 3.将上述菜单添加至app身上
  Menu.setApplicationMenu(menu)


  //当前窗口显示的页面
  win.loadFile("index.html")
  // 窗口关闭
  win.on('close', () => {
    console.log('close')
    win = null
  })
}


// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

Electron笔记,electron,electron,笔记,arcgis

动态创建菜单

index.html代码如下

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <!-- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
  <title>萧寂</title>
</head>

<body>
  <h1>动态创建菜单</h1>
  <button>创建自定义菜单</button>
  <hr>
  <input type="text" placeholder="输入自定义菜单项内容" name="" id="">
  <button>添加菜单项</button>
  <script src="./index.js"></script>
</body>

</html>

index.js代码如下

const remote = require('@electron/remote')
// 找到菜单和菜单项
const Menu = remote.Menu
const MenuItem = remote.MenuItem
window.addEventListener('DOMContentLoaded', () => {
  // 获取按钮
  let btn = document.querySelectorAll('button')
  // 获取输入框
  let input = document.querySelector('input')

  // 自定义全局变量存放菜单项
  let menuItem = new Menu()
  // 点击生成自定义菜单
  btn[0].addEventListener('click', () => {
    // 创建菜单
    let menuFile = new MenuItem({ label: '文件', type: 'normal' })
    let menuEdit = new MenuItem({ label: '编辑', type: 'normal' })
    let customMenu = new MenuItem({ label: '自定义菜单项', submenu: menuItem })
    // 将创建好的菜单添加到menu
    let menu = new Menu()
    menu.append(menuFile)
    menu.append(menuEdit)
    menu.append(customMenu)
    // 将ment放置于app中显示
    Menu.setApplicationMenu(menu)
  })

  // 点击动态添加菜单项
  btn[1].addEventListener('click', () => {
    // 获取当前input输入框当中输入的内容
    let con = input.value.trim()
    if (con) {
      menuItem.append(new MenuItem({ label: con, type: 'normal' }))
      input.value = ''
    }
  })
})

效果图
Electron笔记,electron,electron,笔记,arcgis
点击自定义创建菜单会替换原来的菜单项,在输入框输入菜单名,点击添加菜单项会在菜单栏的自定义菜单里面追加自己添加的菜单项

自定义右键菜单

所有代码都是在index.js里面写的,index.html无代码只引用了index.js
index.js代码如下

const remote = require('@electron/remote')
const Menu = remote.Menu

// 01 创建一个自定义菜单的内容
let contextTemp = [
  { label: 'RunCode' },
  { label: '转到定义' },
  { type: 'separator' },
  {
    label: '其他功能',
    click () {
      console.log("其他功能选项被点击了")  //这个打印不会在主进程显示,而是在桌面版使用ctrl+shifl+i去控制台看
    }
  }
]

// 02 依据上述内容来创建menu
let menu = Menu.buildFromTemplate(contextTemp)

window.addEventListener('DOMContentLoaded', () => {
  // 03 在鼠标右击行为发生后显示出来
  window.addEventListener('contextmenu', (e) => {
    e.preventDefault() //阻止有些元素点击的默认行为
    menu.popup({ window: remote.getCurrentWindow() })  //将当前窗口对象作为popup参数,代表在当前窗口弹出
  }, false)
})

主进程和渲染进程进行通信

同步和异步进行通信

index.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <!-- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
  <title>萧寂</title>
</head>

<body>
  <h1>渲染进程与主进程进行通信</h1>
  <hr>
  <button>渲染主异步操作</button>
  <hr>
  <button>渲染主同步操作</button>
  <script src="./index.js"></script>
</body>

</html>

index.js

const { ipcRenderer } = require('electron')

window.onload = () => {
  // 获取元素
  let abtn = document.querySelectorAll('button')

  // 01 采用异步的API在渲染进程中给主进程发送消息
  abtn[0].addEventListener('click', () => {
    ipcRenderer.send('msg1', 'dataMag')
  })

  // 当前接收主进程的消息
  ipcRenderer.on('msgRe', (ev, data) => {
    console.log('data', data) //主进程回复的异步消息
  })


  // 02 采用同步的方式完成数据的通信
  abtn[1].addEventListener('click', () => {
    let val = ipcRenderer.sendSync('msg2', 'SyncMsg')
    console.log('val', val)  // 主进程回复的同步消息
  })
}

主进程main.js

const { app, BrowserWindow, ipcMain } = require("electron")
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100,
    y: 50, //窗体坐标 
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,  //加入这两行代码就可以正常使用require了,不会报错了
      enableRemoteModule: true
    }
  })
  require('@electron/remote/main').initialize()
  require("@electron/remote/main").enable(win.webContents)
  //当前窗口显示的页面
  win.loadFile("index.html")
  // 窗口关闭
  win.on('close', () => {
    console.log('close')
    win = null
  })
}
// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

// 监听渲染进程发送的消息
ipcMain.on('msg1', (e, data) => {
  console.log('data', data)

  // 主进程给渲染进程发消息
  e.sender.send('msgRe', "主进程回复的异步消息")
})

// 监听渲染进程发送的消息
ipcMain.on('msg2', (e, data) => {
  console.log('data', data)

  // // 主进程给渲染进程发消息
  e.returnValue = '主进程回复的同步消息'
})

通过主进程主动发送消息控制渲染进程作出行为

以下代码没有使用index.html,index.html只是引用了一下index.js
index.js

const { ipcRenderer } = require('electron')

window.onload = () => {

  // 当前接收主进程的消息
  ipcRenderer.on('mtp', (ev, data) => {
    console.log('data', data) //主进程回复的异步消息
  })
}

main.js主进程代码

const { app, BrowserWindow, ipcMain, Menu } = require("electron")
const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100,
    y: 50, //窗体坐标 
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,  //加入这两行代码就可以正常使用require了,不会报错了
      enableRemoteModule: true
    }
  })


  // 主要就是下面这一块
  // 定义菜单
  let temp = [
    {
      label: 'send',
      click () {
        // 点击发送消息,getFocusedWindow获取渲染进程窗口
        BrowserWindow.getFocusedWindow().webContents.send('mtp', '来自主进程发送来的消息')
      }
    }
  ]
  let menu = Menu.buildFromTemplate(temp)
  Menu.setApplicationMenu(menu)
  // 添加了菜单发现ctrl+shift+i不能打开控制台了,因为将原生东西替换掉就不能使用里面的快捷键了
  // 可以使用下面的win.webContents可以控制窗口的所有内容
  win.webContents.openDevTools()  //可以直接运行项目看到控制台



  require('@electron/remote/main').initialize()
  require("@electron/remote/main").enable(win.webContents)
  //当前窗口显示的页面
  win.loadFile("index.html")
  // 窗口关闭
  win.on('close', () => {
    console.log('close')
    win = null
  })
}
// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

Electron笔记,electron,electron,笔记,arcgis
这段代码就是点击菜单的send可以向渲染进程发送消息

渲染进程间的通信

基于本地存储的渲染进程通信

项目结构
Electron笔记,electron,electron,笔记,arcgis

index.html代码如下

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <!-- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
  <title>萧寂</title>
</head>

<body>
  <h1>渲染进程间通信</h1>
  <button>打开窗口2</button>
  <script src="./index.js"></script>
</body>

</html>

index.js代码如下:

const { ipcRenderer } = require('electron')

window.onload = () => {
  // 获取元素
  let btn = document.querySelector('button')

  // 向主进程发送消息
  btn.addEventListener('click', () => {
    ipcRenderer.send('openWin2')

    // 打开窗口二之后保存数据
    localStorage.setItem('name', '萧寂')
  })
}

main.js代码如下

const { app, BrowserWindow, ipcMain } = require("electron")

// 定义全局变量,存放主窗口id
let mainwinid = null

const createWindow = () => {
  // 创建窗口
  let win = new BrowserWindow({
    x: 100,
    y: 50, //窗体坐标 
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,  //加入这两行代码就可以正常使用require了,不会报错了
      enableRemoteModule: true
    }
  })
  require('@electron/remote/main').initialize()
  require("@electron/remote/main").enable(win.webContents)
  //当前窗口显示的页面
  win.loadFile("index.html")
  // 获得主窗口id
  mainwinid = win.id
  // 窗口关闭
  win.on('close', () => {
    console.log('close')
    win = null
  })
}
// 窗口加载和关闭
app.on('ready', createWindow)
app.on("window-all-closed", () => {
  console.log("window-all-closed")
  app.quit()
})

// 接收其他进程发送的数据,然后完成后续的逻辑
ipcMain.on('openWin2', () => {
  // 接收到渲染进程中按钮点击信息之后完成窗口2 的打开
  let subwin1 = new BrowserWindow({
    width: 400,
    height: 300,
    parent: BrowserWindow.fromId(mainwinid),  //代表将index.html主窗口作为这个subwin1的父窗口,这样父窗口关闭,subwin1也能跟着关闭
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,  //加入这两行代码就可以正常使用require了,不会报错了
      enableRemoteModule: true
    }
  })
  subwin1.loadFile('subwin1.html')
  subwin1.on('close', () => {
    subwin1 = null
  })
})

subwin1.html代码如下

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <h2>当前窗口2</h2>
  获取到index.html中的数据:<input type="text" />
  <script src="./subwin1.js"></script>
</body>

</html>

subwin1.js代码如下:

window.onload = () => {
  let input = document.querySelector('input')
  let val = localStorage.getItem('name')
  input.value = val
}

效果图
Electron笔记,electron,electron,笔记,arcgis
剩下的有空再更新吧,基础的笔记基本全了,不过原生electron去写可能性不大,大部分都会以vue等框架写完打包到electron去运行,以上所有的笔记基本满足需求,剩下的等我真正需要用到原生electron时候再继续更新吧,各位可以看上面我链接那个视频继续学习,这套笔记截止到那个视频的第16集该第17集了,我这套笔记就是根据那套视频做的

这里附赠一下electron+vue3+vite打包桌面版的一套视频,外加笔记
electron+vue3+vite视频教程
视频同步笔记,这里有三个系列,按照顺序去看文章来源地址https://www.toymoban.com/news/detail-728538.html

到了这里,关于Electron笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 正确安装Electron、Electron-quick-start和Electron Forge

    Electron Forge引用了Squirrel.windows项目,这导致Electron Forge生成的安装包只能安装在本地用户帐户中。 Or maybe you’re good at reinvent the wheel and can read this part of the documentation. ElectronForge文档 - 扩展 - 制作工具 Squirrel.Windows的Github议题 - Choosing install directory 打开命令行工具,输入 如果正

    2024年02月06日
    浏览(42)
  • 【electron 4】electron配置打包环境

    window需要:ico mac需要:icns linux需要png 借助:electron-icon-builder 安装: 配置package.json scripts 说明: input:icon.png是我需要引入的图标 output:是我将input引入图标所转换不同大小不同格式的图标输出文件 因为我是已有的项目了,所以这里我只需要安装并引入electron-forge,虽然我进

    2024年04月28日
    浏览(35)
  • electron、electron-forge 安装

    npm修改了registry,安装依旧无效 使用cnpm 倒是可以解决,但是 npx electron-forge import 中 Installing dependencies 使用的是npm 给出一次性解决方案: step1:切换npm的下载源,可以使用nrm 进行管理,有很多写的了,就不赘述了。 或者直接修改 (ps:如果你还想修改回来,可以记录一下现

    2024年02月13日
    浏览(34)
  • 【Electron】electron与cljs的处理

    实现效果: 前言: 如何用cljs的方式,编写electron应用,可以实现多窗体应用 要使用ClojureScript(CLJS)编写一个 Electron 应用程序,并实现多窗体功能,您可以按照以下步骤进行操作: 设置开发环境: 安装 Node.js:确保您的计算机上安装了 Node.js,因为 Electron 依赖于它。 安装

    2024年02月07日
    浏览(34)
  • 【Electron】使用electron-builder打包时下载electron失败或慢的解决方案

    问题描述 electron-builder打包时报错信息如下: 解决 该问题是因为electron包需要翻墙获得,需要全局代理,但是太麻烦,我们一般是修改镜像源 在项目根目录下创建.npmrc文件,并且输入以下配置:

    2024年02月11日
    浏览(41)
  • electron-dl用于在Electron中下载多个文件

    electron-dl用于在Electron中下载多个文件 在这个更新的代码中,我们使用了 electron-dl 模块的 download 函数来实现文件下载。我们在主窗口加载完成后,通过循环遍历文件列表,使用 await 等待文件下载完成。下载成功后,我们打印出文件保存的路径。如果下载失败,则打印

    2024年02月03日
    浏览(42)
  • electron应用重启,开机自启动(electron开发常用的方法、优化方案)

    不会了一定先去参考官网:electron官网 主进程中监听 页面中调用 如果不启用非开发环境的话,开发者电脑开机会出现:To run a local app, execute the following on the command line: 弹框,解决方法就是开发环境不启用开机自启动,代码如上 思路:用nodejs去先定时重启应用,在杀死对应软

    2024年02月12日
    浏览(36)
  • electron27+react18集成搭建跨平台应用|electron窗口多开

    electron27-vite4-react18基于electron27结合vite4构建工具快速创建react18跨端应用实践。 版本列表 快速创建react18项目 这里选择使用vite.js构建工具来快速创建一个react18项目。 这样一个简单的react18项目就已经创建完毕了。 安装electron依赖包 注意:electron依赖安装在 devDependencies 里面。

    2024年02月08日
    浏览(55)
  • Electron学习2 使用Electron-vue和Vuetify UI库

    Electron-Vue 是一个使用 Vue.js 构建跨平台桌面应用程序的框架。它基于 Electron,一个使用 JavaScript、HTML 和 CSS 构建跨平台桌面应用程序的开源库。 Electron-Vue 结合了 Vue.js 的灵活性和 Electron 的跨平台能力,使得开发桌面应用程序变得更加简单和高效。以下是一些 Electron-Vue 的主要

    2024年02月11日
    浏览(34)
  • photoshop生成器引入到electron项目(electron与photoshop建立通信)

    Photoshop引入了nodejs,在启动的时候,通过pipe调起nodejs运行时核心generator-builtin,通过KLVR机制与ps进行通信和交互,同时会加载用户编写的扩展。 这里记录一下引入时的踩坑过程 generator-core就是它的源码,electron的主进程是nodejs环境,如果可以将core这套代码在electron的主进程中

    2024年02月13日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包