Electron构建桌面应用程序,服务于项目的自主学习记录(持续更新...

无所畏惧地面对未知,并将其视为成长的机会

大纲

官网

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

快速入门

1.安装node.js -- 这里推荐用nvm管理

一.nvm安装node方式以及可能出现问题的解决方案

1.window下安装并使用nvm

2.nvm安装及安装后node不能使用

3.node.js安装后在命令行输入"node -v " 查看版本提示:'node' 不是内部或外部命令,也不是可运行的程序的解决方法

4.检查node/npm是否正确安装 node -v && npm -v

2.脚手架创建

mkdir my-electron-app && cd my-electron-app

npm init

javascript 复制代码
//npm init 后 package.json
{
  "name": "my-electron-app",
  "version": "1.0.0",
  "description": "Hello World!",
  "main": "main.js",  //!!!main代表主进程文件,需要根据配置的新建主进程文件名(这里init会存在为index.js情况,手动改为main.js)
  "author": "Jane Doe",
  "license": "MIT"
}

3.electron 包安装到应用的开发依赖

javascript 复制代码
npm install --save-dev electron

//package.json 修改
{
  "scripts": {
    "start": "electron ."
  }
}

//首次启动 
//此时main.js主进程未创建,Electron应用在启动时找不到指定的入口文件,在package.json配置的main
npm start

4.创建主进程(main.js)并启动项目

1.创建页面
html 复制代码
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>
2.配置main.js

新建main.js文件 此时 npm start 不会抛出异常

javascript 复制代码
const { app, BrowserWindow } = require('electron')
const createWindow = () => {
    const win = new BrowserWindow({
      width: 800,
      height: 600,
      show: false, //ready-to-show 解决闪烁
      autoHideMenuBar: true, // 隐藏顶部file menu
      backgroundColor: '#fff', //对于一个复杂的应用,ready-to-show 可能发出的太晚,会让应用感觉缓慢。 在这种情况下,建议立刻显示窗口,并使用接近应用程序背景的 backgroundColor
    })
    //优雅地显示窗口 -- 解决窗口闪烁问题
    win.once('ready-to-show', () => {
        win.show()
        win.webContents.openDevTools({ mode: 'detach' }) //开发者工具
    })
    win.loadFile('index.html') // 加载项目使用loadURL
    win.maximize() //窗口最大化
}

//在 Electron 中,只有在 app 模块的 ready 事件被激发后才能创建浏览器窗口。 您可以通过使用 app.whenReady() API来监听此事件
app.whenReady().then(() => {
    createWindow()
    // 处理 macOS 特有的行为,提供一致的用户体验
    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})

//关闭所有窗口时退出应用 (Windows & Linux)
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})
3.启动项目 -- 效果

进阶 -- 基于项目场景功能使用

场景一:web交互打开文件系统

javascript 复制代码
// main.js 
const { app, BrowserWindow,dialog,ipcMain } = require('electron') 
// ipcMain 从主进程到渲染进程的异步通信
// dialog 显示用于打开和保存文件、警报等的!!本机系统!!对话框
const path = require('path')
const createWindow = () => {
    const win = new BrowserWindow({
      width: 800,
      height: 600,
      show: false,
      backgroundColor: '#fff',
      autoHideMenuBar: true,
      webPreferences: {// 网页功能设置
        preload: path.join(__dirname, 'preload.js')// 在页面运行其他脚本之前预先加载指定的脚本
      }
    })
    win.once('ready-to-show', () => {
        win.show()
        win.webContents.openDevTools({ mode: 'detach' })
    })
    win.loadFile('index.html')
    //ipcMain,用于在主进程中处理渲染进程(即前端页面)发送的异步消息。具体来说,这个方法的作用是监听名为 dialog:openProject 的事件(preload.js发送),并在事件触发时执行指定的回调函数。
    ipcMain.handle('dialog:openProject', async () => {
        const { canceled, filePaths } = await dialog.showOpenDialog(win, {
            properties: ['openFile'],
            filters: [
                { name: 'Project Files', extensions: ['db'] },
            ]
        })
        if (canceled) {
            return
        } else {
            return filePaths[0]
        }
    })
}
app.whenReady().then(() => {
    createWindow()
    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})
javascript 复制代码
// preload.js
// contextBridge 和 ipcRenderer 结合使用的主要目的是在 Electron 应用程序中实现安全的进程间通信(Inter-Process Communication, IPC)。
// contextBridge 用于在渲染进程和主进程之间安全地传递数据和函数
// ipcRenderer 用于在渲染进程中与主进程进行通信
const {contextBridge, ipcRenderer} = require('electron')
//exposeInMainWorld(key,api) -- 将api注入到window,web通过window.myAPI.selectProject于主进程通信
contextBridge.exposeInMainWorld('myAPI', {
    selectProject: () => ipcRenderer.invoke('dialog:openProject'), 
})

场景二:区分开发和生产环境处理开发者工具

javascript 复制代码
win.once('ready-to-show', () => {
        win.show()
		if (!app.isPackaged) {
			console.log(`[main] open dev tools`)
			mainWindow.webContents.openDevTools({ mode: 'detach' })
		}
}

持续更新...

相关推荐
DT——10 分钟前
前端基础面试题·第四篇——Vue(其二)
前端·javascript·vue.js
Jiaberrr14 分钟前
如何在uniapp(vue2)中使用Vue Router和router-view进行页面管理
前端·javascript·vue.js·uni-app
蜡笔小新星20 分钟前
Python Kivy 事件与交互教程
开发语言·经验分享·python·学习·交互
就叫飞六吧21 分钟前
dockerpull
前端·javascript·css·vue.js·css3
我不会画饼鸭21 分钟前
vue快速上手
前端·javascript·vue.js
深情废杨杨27 分钟前
前端vue-安装pinia,它和vuex的区别
前端·javascript·vue.js
&小胖&39 分钟前
threejs学习
javascript·学习·threejs
全优统计41 分钟前
学习干货IF=93.6!开发临床预测模型:分步指南
经验分享·科技·学习·数据分析
TttHhhYy1 小时前
echarts的option,设置折线图鼠标悬浮显示数据
前端·javascript·echarts
百锦再1 小时前
45岁被裁员的程序员,何去何从?
人工智能·python·学习·ai