# electron **Repository Path**: lonsun/electron ## Basic Information - **Project Name**: electron - **Description**: 公开课-electron源码 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2020-11-03 - **Last Updated**: 2024-12-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### 简介 + [官网](https://www.electronjs.org/) + Electron是由GitHub开发,使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序 + Electron 可以让你使用纯 [JavaScript](https://www.w3cschool.cn/javascript/) 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用 + 在PC端混合app开发中,nwjs和electron都是可选的方案,它们都是基于Chromium和Node的结合体, 而electron相对而言是更好的选择方案,它的社区相对比较活跃,bug比较少,文档先对利索简洁。 + electron 相对来说比 [nw.js](https://www.codebye.com/tag/nw-js) 靠谱。有一堆成功的案例:Atom 编辑器 2. Slack (那个独角兽公司)3. Visual Studio Code 4. WordPress 等等。。 + Node. js 的所有 [内置模块 ](https://nodejs.org/api/)都在Electron中可用, 第三方 node 模块中也完全支持 (包括 [原生模块 ](https://www.electronjs.org/docs/tutorial/using-native-node-modules))。 + Electron 还为开发原生桌面应用程序提供了一些额外的内置模块。 某些模块仅在主进程中可用, 有些仅在渲染进程 (web 页) 中可用, 而有些在这两个进程中都可以使用。 #### 安装electron + npm init + cnpm I electron –S + npx electron #### 5分钟快速上手 + 创建main.js文件 ```js const electron = require('electron') const app = electron.app app.on('ready', ()=>{ new electron.BrowserWindow({ width: 800, height: 300 }) }) ``` + 将main.js文件配置为入口文件,通过npm run start启动 ```js { "name": "electron-demo", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "electron ." }, "author": "", "license": "ISC", "dependencies": { "electron": "^8.3.0" } } ``` + 通过BrowserWindow的实例来配置加载的页面文件 ```js app.on('ready', ()=>{ const mainWindow = new BrowserWindow({ width: 800, height: 500 }) mainWindow.loadFile('./index.html') }) ``` #### 主进程和渲染进程 Electron 运行 `package.json` 的 `main` 脚本的进程被称为**主进程**。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。 由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它的叫**渲染进程**的进程中。 在普通的浏览器中,web页面通常在沙盒环境中运行,并且无法访问操作系统的原生资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。 ctrl+shift+i打开渲染进程调试 ```js app.on('ready', ()=>{ const mainWindow = new BrowserWindow({ width: 800, height: 500 }) mainWindow.loadFile('./index.html') const mainWindow2 = new BrowserWindow({ width: 800, height: 500 }) mainWindow2.loadFile('./index2.html') }) ``` #### 自定义原生菜单 ##### 自定义菜单 ```js const template = [ { label: '文件', submenu: [ { label: '新建窗口' } ] }, { label: '编辑', submenu: [ { label: '新建窗口' } ] } ] const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) ``` ##### 给菜单定义点击事件 ```js submenu: [ { label: '新建窗口', click: ()=>{ const newMainWindow = new BrowserWindow({ width: 300, height: 300 }) newMainWindow.loadFile('./new.html') } } ] ``` ##### 抽离菜单定义 ```js const { BrowserWindow, Menu} = require('electron') const template = [ { label: '文件', submenu: [ { label: '新建窗口', click: ()=>{ const newMainWindow = new BrowserWindow({ width: 300, height: 300 }) newMainWindow.loadFile('./new.html') } } ] }, { label: '编辑', submenu: [ { label: '新建窗口' } ] } ] const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) ``` ```js require('./menu') ``` #### 打开调式 mainWindow.webContents.openDevTools() #### 自定义顶部菜单 + 通过BrowserWindow.frame创建无边框窗口 + 自定义窗口 ```html
``` + icon + backgroundColor #### 定义右键菜单 js>index.js ```js const { remote } = require('electron') const template = [ { label: '粘贴' }, { label: '赋值' } ] const menu = remote.Menu.buildFromTemplate(template) window.addEventListener('contextmenu', (e) => { console.log(123) e.preventDefault() menu.popup({ window: remote.getCurrentWindow() }) }) ``` 在index.html中引入 ```js Document ``` 能够在html中使用node方法 ```js const mainWindow = new BrowserWindow({ width: 800, height: 500, webPreferences: { nodeIntegration: true } }) ``` #### 点击打开浏览器 + html ```html 打开浏览器 ``` + js ```js const { shell } = require('electron') const aEL = document.querySelector('#a1') aEL.onclick = function(e) { e.preventDefault() const url = this.getAttribute('href') shell.openExternal(url) } ``` #### 自动刷新页面 + 安装插件 ```js cnpm install --save-dev electron-reloader ``` + 在入口引入插件 ```js const reloader = require('electron-reloader') reloader(module,{}) ``` #### 拖拽文件进行读取 + 定义拖拽到指定区域 ```html
``` ```css #drop { width: 300px; height: 500px; background: hotpink; } ``` + 添加拖拽事件获取文件路径 ```js // 添加拖拽 const dropEl = document.querySelector('#drop') dropEl.addEventListener('drop', function(e) { if(e.dataTransfer.files.length === 1) { const filePath = e.dataTransfer.files[0].path } }) dropEl.addEventListener('dragover', function (e) { e.preventDefault() }) ``` + 引入fs模块进行读取 ```js const fs = require('fs') // 添加拖拽 const dropEl = document.querySelector('#drop') dropEl.addEventListener('drop', function(e) { if(e.dataTransfer.files.length === 1) { const filePath = e.dataTransfer.files[0].path const fileContent = fs.readFileSync(filePath).toString() this.innerText = fileContent } }) dropEl.addEventListener('dragover', function (e) { e.preventDefault() }) ``` #### 打开对话框 ##### 读取文件 + 定义点击事件 ```js ``` + 定义事件函数 ```js // 打开对话框 function openFile() { const res = remote.dialog.showOpenDialogSync({ title: '选择文件', buttonLabel: '哈哈', filters: [ { name: 'Custom File Type', extensions: ['js','html','json'] }, ] }) const fileContent = fs.readFileSync(res[0]).toString() dropEl.innerText = fileContent } ``` ##### 保存文件 + 定义点击事件 ```html ``` + 事件函数 ```js // 保存对话框 function saveFile() { const res = remote.dialog.showSaveDialogSync({ title: '保存文件', buttonLabel: '保存文件', filters: [ { name: 'index', extensions: ['js'] }, ] }) fs.writeFileSync(res, 'hahhdasdshafsdahjk') } ``` ##### 消息提示 + 定义事件 ```html ``` + 事件函数 ```js // 提示信息 function messageBox() { remote.dialog.showMessageBoxSync({ type: 'none', buttons: ['确定'], title: '提示消息', message: '明天会下雨呦' }) } ``` #### 定义快捷键 ##### 主线程定义 + 引入 ```js const { app, BrowserWindow, globalShortcut } = require('electron') ``` + 在ready中注册快捷键 ```js const { app, BrowserWindow, globalShortcut } = require('electron') ``` ##### 渲染进程定义 + 通过remote注册 ```js // 定义快捷键 remote.globalShortcut.register('Ctrl+O', () => { console.log('ctrl+o') }) ``` + 定义快捷键最大、最小、关闭窗口 ```js globalShortcut.register('Ctrl+T',()=>{ mainWindow.unmaximize(); }) globalShortcut.register('Ctrl+H',()=>{ mainWindow.close() }) globalShortcut.register('Ctrl+M',()=>{ mainWindow.maximize() }) ``` #### 渲染进程和主线程通讯 + 定义按钮 ```html
``` + 事件函数 ```js function maxWindow() { ipcRenderer.send('max-window') } ``` + 主线程定义事件 ```js ipcMain.on('max-window', () => { mainWindow.maximize() }) ``` + 传参 ```js let windowSize = 'unmax-window' function maxWindow() { windowSize = windowSize === 'max-window' ?'unmax-window':'max-window' ipcRenderer.send('max-window',windowSize) } ``` + 接收参数 ```js ipcMain.on('max-window', (event,arg) => { console.log(arg) if(arg === 'unmax-window') return mainWindow.maximize(); mainWindow.unmaximize() }) ``` + 通过isMaximized判断当前窗口 #### 网络请求 ```js async function getMsg () { const res = await fetch('http://127.0.0.1:3006/api/person').then(res=>res.json()) console.log(res) } ``` #### electron结合react ##### 利用react初始化项目 + npx create-react-app electron-react + cd electron-react + npm start ##### 安装electron + cnpm i electron + 添加electron的任务 ```js "main": "main.js", "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "electron": "electron ." }, ``` + 添加main.js ```js const {app, BrowserWindow} = require('electron') function createWindow () { // Create the browser window. const mainWindow = new BrowserWindow({ width: 800, height: 600 }) // Open the DevTools. // mainWindow.webContents.openDevTools() } app.whenReady().then(() => { createWindow() }) ``` + 加载react项目 ```js mainWindow.loadURL('http://localhost:3000/') ``` #### electron结合vue 同react #### electron打包 + 将vue项目打包 + 修改electron引入的文件 ```js mainWindow.loadFile('./dist/index.html') ``` + 安装electron-packager ```js "packager": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./favicon.ico" ``` ​