Electron + Vite + Vue 项目中的 IPC 通信三层封装实践

Electron + Vite + Vue 项目中的 IPC 通信三层封装实践

electron-vite-vue 是一个由社区维护的轻量级脚手架项目,集成了:

  • ⚡ Vite:快速现代的构建工具
  • 🧩 Vue 3:默认的前端 UI 框架
  • 🖥️ Electron:跨平台桌面应用运行时

它帮助开发者快速搭建出具有前后端隔离、热更新、预加载脚本支持的 Electron 桌面应用开发环境,适合个人工具、跨平台客户端、管理后台等场景。


在这个基础上,我们希望进一步规范主进程与渲染进程之间的通信逻辑,封装一套结构清晰的 IPC 模块,以便项目功能增长时也能保持良好的可维护性。

本文将介绍如何实现这一目标,包括:

  • 主进程逻辑统一注册
  • Preload 中安全暴露 API
  • 渲染进程中统一调用

📦 项目结构示意

复制代码
electron-vite-vue/
├── electron/
│   ├── main/
│   │   └── ipcHandlers.ts     ← 主进程统一注册 IPC
│   └── preload/
│       └── index.ts           ← contextBridge 暴露 API
├── src/
│   ├── App.vue
│   ├── main.ts
│   └── types/
│       └── electron-api.d.ts  ← 类型提示(可选)

🧠 目标通信结构

渲染进程 → Preload 暴露 API → 主进程处理逻辑 → 返回数据或执行动作


🧱 1. 主进程封装:ipcHandlers.ts

ts 复制代码
// electron/main/ipcHandlers.ts
import { app, ipcMain, BrowserWindow, dialog, shell } from 'electron'

export function setupIpcHandlers(win: BrowserWindow) {
  ipcMain.handle('get-app-version', () => {
    return app.getVersion()
  })

  ipcMain.handle('select-file', async () => {
    return await dialog.showOpenDialog({ properties: ['openFile'] })
  })

  ipcMain.on('window-minimize', () => win.minimize())

  ipcMain.on('open-external', (_, url) => {
    shell.openExternal(url)
  })
}

然后在主进程入口(如 electron/main/index.ts)注册:

ts 复制代码
import { setupIpcHandlers } from './ipcHandlers'

// 创建窗口后调用
setupIpcHandlers(win)

🛡️ 2. Preload 层暴露:preload/index.ts

ts 复制代码
// electron/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron'

contextBridge.exposeInMainWorld('electronAPI', {
  getAppVersion: () => ipcRenderer.invoke('get-app-version'),
  selectFile: () => ipcRenderer.invoke('select-file'),
  minimizeWindow: () => ipcRenderer.send('window-minimize'),
  openExternal: (url: string) => ipcRenderer.send('open-external', url),
  onNavigate: (callback: (path: string) => void) => {
    ipcRenderer.on('navigate-to', (_, path) => callback(path))
  }
})

💻 3. 渲染进程使用示例:App.vue

ts 复制代码
<script setup lang="ts">
const checkVersion = async () => {
  const version = await window.electronAPI.getAppVersion()
  console.log('当前版本:', version)
}

const selectAndLogFile = async () => {
  const result = await window.electronAPI.selectFile()
  if (!result.canceled && result.filePaths.length > 0) {
    console.log('文件路径:', result.filePaths[0])
  }
}

const openGitHub = () => {
  window.electronAPI.openExternal('https://github.com/electron-vite/electron-vite-vue')
}
</script>

<template>
  <button @click="checkVersion">获取版本</button>
  <button @click="selectAndLogFile">选择文件</button>
  <button @click="openGitHub">打开 GitHub</button>
</template>

💡 4. 类型提示增强(可选):electron-api.d.ts

ts 复制代码
// src/types/electron-api.d.ts
export interface ElectronAPI {
  getAppVersion(): Promise<string>
  selectFile(): Promise<{ canceled: boolean, filePaths: string[] }>
  minimizeWindow(): void
  openExternal(url: string): void
  onNavigate(cb: (path: string) => void): void
}

declare global {
  interface Window {
    electronAPI: ElectronAPI
  }
}

并在 tsconfig.json 中添加类型目录:

json 复制代码
{
  "compilerOptions": {
    "types": ["vite/client", "./src/types/electron-api"]
  }
}

🧪 5. 测试建议

  1. 确保 preload 在 vite.config.ts 中配置正确
  2. 确保你使用 contextIsolation: true、nodeIntegration: false
  3. 主进程与渲染进程中 API 名称一致,避免大小写错误

✅ 总结

通过上述结构,我们实现了:

  • IPC 注册集中管理,主进程清晰职责分离
  • 渲染进程只需 window.electronAPI.xxx() 调用
  • 满足 Electron 安全通信规范(基于 contextBridge)

这为后续功能扩展打下了良好基础,适用于中大型 Electron 桌面应用项目。


如需示例代码,可参考项目模板:electron-vite-vue

欢迎点赞、收藏、分享 🙌

相关推荐
Hilaku30 分钟前
为什么我劝应届生不要去创业公司写前端?
前端·javascript·程序员
高级程序源1 小时前
hive电商平台商品销售数据分析与趋势预测45659-计算机课程设计、毕业设计
vue.js·hive·spring boot·mysql·数据分析·django·课程设计
晓得迷路了1 小时前
栗子前端技术周刊第 149 期 - Vite+ 1.0、Preact 11、Next.js 16.4...
前端·javascript·react.js
前端一小卒1 小时前
搜索 API 额度用完返回空数组,Agent 就开始一本正经地胡说
前端·javascript·node.js
ljt27249606612 小时前
Vue笔记(十三)--mixin
vue.js·笔记
w2sfot2 小时前
AI时代,JS加密还有效吗?
开发语言·前端·javascript
haluhalu.2 小时前
Agent = LLM + 上下文 + 工具(含观察 / 动作空间、ReAct 循环)
前端·javascript·人工智能·python·react.js·机器学习·个人开发
子兮曰8 小时前
把 649 种文件格式塞进一个网页里:一个「文件不出浏览器」的预览器
前端·javascript·后端
paopaokaka_luck11 小时前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis
溪语流沙11 小时前
【每天一个CSS | Day19】流光文字与一笔写成的手写签名
前端·javascript·css