electron入门使用
- 背景
- [how to start](#how to start)
-
- [第一步 创建一个vite-vue3项目](#第一步 创建一个vite-vue3项目)
- [第二步 装各种依赖](#第二步 装各种依赖)
- [第三步 配置](#第三步 配置)
- 启动
- 重写关闭、隐藏、最大化最小化
背景
最近对electron比较感兴趣,折腾一段时间后有了点眉目,记录一下
how to start
第一步 创建一个vite-vue3项目
bash
# 选vue3但是不要用ts,用js会舒服得多
npm create vite -n test-electron
第二步 装各种依赖
bash
# 命令1
npm i electron -d -s
# 命令2
npm install vite-plugin-optimizer --save-dev
# 命令3
npm install vite-plugin-node-polyfills --save-dev
# 命令4
npm install @electron/remote
# 命令5
npm install element-plus --save
# 命令6
npm i vue-router
注意,命令1可能需要反复执行反复失败才会成功,推测是网的原因,而且我自己测试用yarn和pnpm必报错,只有npm才行
第三步 配置
vite.config.js
js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
import optimizer from 'vite-plugin-optimizer'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(), // 添加 Node.js 内置模块的 polyfill
nodePolyfills({
include: ['path'],
globals: { Buffer: true, global: true, process: true },
protocolImports: true,
}),
optimizer({
electron: `const { ipcRenderer } = require('electron'); export { ipcRenderer };`
})
],
build: {
rollupOptions: {
output: {
manualChunks: {
// 将第三方库分割到单独的代码块
'vendor': ['element-plus'],
}
}
}
},
server: {
port: 8888,
cors: true, // 允许跨域
hmr: true, // 开启热更新
},
"base": "./"
})
package.json
json
{
"name": "ele-pro",
"private": true,
"version": "0.0.0",
"type": "module",
"main": "electron/main.cjs",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"electron:serve": "vite build && electron ."
},
"dependencies": {
"@electron/remote": "^2.1.2",
"electron-reload": "^2.0.0-alpha.1",
"element-plus": "^2.9.7",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"electron": "^35.1.3",
"vite": "^6.2.0",
"vite-plugin-node-polyfills": "^0.23.0",
"vite-plugin-optimizer": "^1.4.3"
}
}
一定要重点关注入口:"main": "electron/main.cjs",和electron启动命令:"electron:serve": "vite build && electron ."
electron入口
在项目的根目录下新建文件夹/electron。
在文件夹中新建文件main.cjs
注意,一定要是.cjs,不是.js
js
// 控制应用生命周期和创建原生浏览器窗口的模组
const { app, BrowserWindow, Menu } = require('electron')
const path = require('path')
require('@electron/remote/main').initialize()
function createWindow() {
// 创建浏览器窗口
const mainWindow = new BrowserWindow({
width: 1200,
height: 800,
frame: false, // 隐藏默认的标题栏
webPreferences: {
// 书写渲染进程中的配置
nodeIntegration: true, //开启true这一步很重要,目的是为了vue文件中可以引入node和electron相关的API
contextIsolation: false, // 可以使用require方法
},
})
require('@electron/remote/main').enable(mainWindow.webContents)
let env = 'pro'
// 配置热更新
if (env == 'pro') {
const elePath = path.join(__dirname, '../node_modules/electron')
require('electron-reload')('../', {
electron: require(elePath),
})
// 热更新监听窗口
mainWindow.loadURL('http://localhost:8888')
// 打开开发工具
mainWindow.webContents.openDevTools()
} else {
// 生产环境中要加载文件,打包的版本
// Menu.setApplicationMenu(null)
// 加载 index.html
mainWindow.loadFile(path.resolve(__dirname, '../dist/index.html')) // 新增
}
}
// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
// 关闭默认菜单栏
Menu.setApplicationMenu(null)
createWindow()
app.on('activate', function () {
// 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
// 打开的窗口,那么程序会重新创建一个窗口。
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此,通常对程序和它们在
// 任务栏上的图标来说,应当保持活跃状态,直到用户使用 Cmd + Q 退出。
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
启动
打开两个终端窗口,需要都在该项目的根目录。
先运行npm run dev
再运行npm run electron:serve
这样,electron就能根据vue的内容实时渲染
重写关闭、隐藏、最大化最小化
在vue的根组件App.vue中:
html
<script setup>
import {
Close,
FullScreen,
ArrowDown
} from '@element-plus/icons-vue'
import { getCurrentWindow } from '@electron/remote'
// 关闭
const closeApp = () => {
const currentWindow = getCurrentWindow()
currentWindow.close()
}
// 全屏/退出全屏应用
const fullScreenApp = () => {
const currentWindow = getCurrentWindow()
if (currentWindow.isFullScreen()) {
currentWindow.setFullScreen(false)
} else {
currentWindow.setFullScreen(true)
}
}
// 最小化应用
const hideApp = () => {
const currentWindow = getCurrentWindow()
currentWindow.minimize()
}
</script>
<template>
<div>
<div style="padding: 10pt; text-align: right;">
<el-button type="warning" size="small" circle :icon="ArrowDown" @click="hideApp"></el-button>
<el-button type="success" size="small" :icon="FullScreen" circle @click="fullScreenApp" />
<el-button type="danger" size="small" :icon="Close" circle @click="closeApp" />
</div>
<router-view></router-view>
</div>
</template>
<style scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
color: #2c3e50;
}
</style>
先到这里,后面有什么好玩的继续更新