【前端记事】关于electron的入门使用

electron入门使用

背景

最近对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>

先到这里,后面有什么好玩的继续更新

相关推荐
开开心心就好17 分钟前
Word图片格式调整与转换工具
java·javascript·spring·eclipse·pdf·word·excel
Stringzhua26 分钟前
JavaScript【5】DOM模型
开发语言·javascript·ecmascript
90后小陈老师27 分钟前
WebXR教学 07 项目5 贪吃蛇小游戏
前端·数码相机
一口一个橘子30 分钟前
[ctfshow web入门] web118
前端·web安全·网络安全
GanGuaGua1 小时前
Vue3:脚手架
前端·javascript·css·vue.js·vue
weixin_431600441 小时前
使用 Vue Tour 封装一个统一的页面引导组件
javascript·vue.js·ecmascript
鸡吃丸子2 小时前
常见的实时通信技术(轮询、sse、websocket、webhooks)
前端·websocket·状态模式
胡斌附体2 小时前
vue添加loading后修复页面渲染问题
前端·javascript·vue.js·渲染·v-if·异步加载
Dontla2 小时前
Webpack DefinePlugin插件介绍(允许在编译时创建JS全局常量,常量可以在源代码中直接使用)JS环境变量
运维·javascript·webpack
酷爱码3 小时前
css中的 vertical-align与line-height作用详解
前端·css