Skip to content

Electron 入门教程:结合 Vue 框架理解整体运行原理(AI 文档~~)

什么是 Electron?

Electron 是一个开源框架,允许开发者使用 Web 技术(HTML、CSS 和 JavaScript)构建跨平台的桌面应用程序。它由 GitHub 开发,广泛用于创建如 Visual Studio Code、Slack 和 Discord 等桌面应用。

Electron 的核心是结合了 Chromium(提供浏览器渲染引擎)和 Node.js(提供后端 JavaScript 运行时),使得开发者可以在一个环境中同时使用 Web 技术和 Node.js 的能力。本教程将使用 Vue 框架作为渲染进程的前端框架。

本教程的目标

  • 理解 Electron 的运行原理。
  • 掌握 Electron 的核心组件(主进程、渲染进程、进程通信等)。
  • 集成 Vue 框架,完成一个简单的 Electron + Vue 应用。
  • 提供注意事项和常见问题解答。

Electron 的运行原理

核心组件

Electron 应用程序由以下核心部分组成:

  1. 主进程(Main Process)

    • 运行在 Node.js 环境中,负责应用程序的生命周期管理(如启动、关闭、窗口创建等)。
    • 主进程通过 main.js(或其他命名的主文件)定义,通常是应用的入口点。
    • 负责创建和管理窗口(BrowserWindow),以及与操作系统的交互(如文件系统、系统托盘等)。
  2. 渲染进程(Renderer Process)

    • 每个窗口运行一个独立的渲染进程,基于 Chromium 引擎,负责显示 UI。
    • 在本教程中,我们将使用 Vue 框架来构建渲染进程的 UI,结合 HTML、CSS 和 JavaScript。
    • 渲染进程与主进程隔离,不能直接访问系统资源。
  3. 进程间通信(IPC)

    • 主进程和渲染进程通过 IPC(Inter-Process Communication) 进行通信。
    • 渲染进程通过 ipcRenderer 模块向主进程发送消息,主进程通过 ipcMain 模块处理消息。
    • 例如,点击 Vue 组件中的按钮触发文件保存操作。
  4. Chromium 和 Node.js 的结合

    • Chromium 提供 Web 渲染能力,支持现代 Web 技术(如 ES6+、CSS3、Web APIs)。
    • Node.js 提供文件系统、网络、模块管理等后端功能。
    • Vue 框架运行在渲染进程中,利用 Chromium 的能力实现动态 UI。

Electron 的运行流程

  1. 启动时,Electron 加载主进程脚本(通常是 main.js)。
  2. 主进程创建 BrowserWindow 实例,加载 HTML 文件作为窗口内容。
  3. HTML 文件运行在渲染进程中,执行 Vue 应用的前端代码。
  4. 当渲染进程需要访问系统资源(如打开文件对话框),通过 IPC 向主进程发送请求。
  5. 主进程处理请求,调用 Node.js 或系统 API,并将结果通过 IPC 返回给渲染进程。

开发环境搭建

前置要求

  • Node.js:建议安装最新 LTS 版本(推荐 v16 或更高)。
  • npm:Node.js 自带的包管理工具。
  • 代码编辑器:推荐 Visual Studio Code。
  • 操作系统:Windows、macOS 或 Linux 均可。

安装步骤

  1. 安装 Node.js
    访问 Node.js 官网 下载并安装 LTS 版本。安装完成后,验证版本:

    bash
    node -v
    npm -v
  2. 安装 Vue CLI
    安装 Vue CLI 用于创建 Vue 项目:

    bash
    npm install -g @vue/cli
  3. 创建项目目录
    创建一个空文件夹(如 my-electron-vue-app)并进入:

    bash
    mkdir my-electron-vue-app
    cd my-electron-vue-app
  4. 初始化 Vue 项目
    使用 Vue CLI 创建项目,选择默认配置(Vue 3):

    bash
    vue create .
    • 选择 Default ([Vue 3] preset)
    • 完成后,项目会包含 src/App.vue 等文件。
  5. 安装 Electron
    安装 Electron 作为开发依赖:

    bash
    npm install electron --save-dev
  6. 配置 package.json
    编辑 package.json,添加 Electron 启动脚本和主进程入口:

    json
    {
      "name": "my-electron-vue-app",
      "version": "0.1.0",
      "main": "main.js",
      "scripts": {
        "start": "electron .",
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build"
      }
    }
  7. 安装 electron-builder(可选)
    为后续打包应用,安装 electron-builder

    bash
    npm install electron-builder --save-dev

创建一个简单的 Electron + Vue 应用

我们将创建一个简单的 Electron 应用,使用 Vue 框架在渲染进程中显示一个按钮,点击按钮后通过 IPC 调用主进程打开文件对话框。

项目结构

my-electron-vue-app/
├── main.js           // 主进程脚本
├── preload.js        // 预加载脚本
├── public/           // Vue 静态资源
│   └── index.html    // 渲染进程的 HTML 文件
├── src/              // Vue 源代码
│   ├── App.vue       // Vue 根组件
│   ├── main.js       // Vue 入口文件
│   └── components/   // Vue 组件
├── package.json      // 项目配置文件
└── node_modules/     // 依赖文件夹

步骤 1:创建主进程脚本(main.js)

主进程负责创建窗口并加载 Vue 构建的 HTML 文件。

javascript
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const path = require('path');

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      enableRemoteModule: false,
      nodeIntegration: false,
    },
  });

  // 开发环境下加载 Vue dev server,生产环境下加载构建后的文件
  const isDev = process.env.NODE_ENV !== 'production';
  if (isDev) {
    win.loadURL('http://localhost:8080');
  } else {
    win.loadFile(path.join(__dirname, 'dist/index.html'));
  }
}

// 处理文件选择对话框
ipcMain.on('open-file-dialog', (event) => {
  dialog
    .showOpenDialog({
      properties: ['openFile'],
    })
    .then((result) => {
      if (!result.canceled) {
        event.sender.send('selected-file', result.filePaths[0]);
      }
    })
    .catch((err) => {
      console.error(err);
    });
});

app.whenReady().then(() => {
  createWindow();
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

步骤 2:创建预加载脚本(preload.js)

预加载脚本暴露安全的 IPC API 给渲染进程。

javascript
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  send: (channel, data) => {
    let validChannels = ['open-file-dialog'];
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data);
    }
  },
  receive: (channel, func) => {
    let validChannels = ['selected-file'];
    if (validChannels.includes(channel)) {
      ipcRenderer.on(channel, (event, ...args) => func(...args));
    }
  },
});

步骤 3:修改 Vue 入口文件(src/main.js)

Vue 入口文件初始化 Vue 应用并监听 IPC 消息。

javascript
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);

// 监听 IPC 消息
window.electronAPI.receive('selected-file', (path) => {
  app.config.globalProperties.$selectedFile = path; // 全局存储文件路径
});

app.mount('#app');

步骤 4:创建 Vue 根组件(src/App.vue)

Vue 组件实现 UI 和交互逻辑。

vue
<template>
  <div id="app">
    <h1>Welcome to My Electron + Vue App</h1>
    <button @click="openFile">Open a File</button>
    <p>
      {{ selectedFile ? `Selected file: ${selectedFile}` : 'No file selected' }}
    </p>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      selectedFile: null,
    };
  },
  methods: {
    openFile() {
      window.electronAPI.send('open-file-dialog');
    },
  },
  created() {
    // 监听全局文件路径更新
    this.$watch(
      () => this.$app.$selectedFile,
      (newPath) => {
        this.selectedFile = newPath;
      },
    );
  },
};
</script>

<style>
#app {
  font-family: Arial, sans-serif;
  text-align: center;
  padding: 20px;
}
button {
  padding: 10px 20px;
  font-size: 16px;
  cursor: pointer;
}
</style>

步骤 5:修改 public/index.html

确保 HTML 文件正确加载 Vue 应用。

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Electron + Vue App</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

步骤 6:运行应用

  1. 启动 Vue 开发服务器

    bash
    npm run serve
  2. 在新终端中启动 Electron

    bash
    npm start

    这将启动 Electron 应用,连接到 Vue 开发服务器(http://localhost:8080),显示一个窗口。点击“Open a File”按钮会弹出文件选择对话框,选择文件后路径将显示在窗口中。

  3. 打包应用(可选): 构建 Vue 应用并打包 Electron:

    bash
    npm run build
    npx electron-builder

    确保 electron-builder 已配置好,参考其文档。

注意事项

  1. 安全性

    • 始终启用 contextIsolation 和禁用 nodeIntegration,防止渲染进程直接访问 Node.js API。
    • 使用 preload.js 暴露受限的 API,避免安全漏洞。
    • 验证 IPC 通道,防止未授权的消息传递。
  2. 性能优化

    • 避免加载过多的外部资源,减少应用启动时间。
    • 使用 Vue 的生产构建(npm run build)优化性能。
    • 对于大型应用,考虑代码分割和懒加载。
  3. 跨平台兼容性

    • 测试应用在 Windows、macOS 和 Linux 上的表现,确保路径处理(如 path.join)兼容。
    • 注意 macOS 特殊行为(如 activate 事件)。
  4. 调试

    • 打开开发者工具(右键 > Inspect 或 Ctrl+Shift+I)调试 Vue 组件。
    • 使用 Vue Devtools 扩展调试 Vue 应用。
    • 使用 console.log 或 Electron 的日志工具调试主进程。
    • 检查 package.json 中的依赖版本,确保与 Electron 和 Vue 兼容。
  5. 常见问题

    • 错误:Cannot find module 'electron'
      确保已安装 Electron,运行 npm install
    • 窗口显示空白
      检查 Vue 开发服务器是否运行,或 dist/index.html 是否正确生成。
    • IPC 通信失败
      确保 preload.js 正确配置,通道名称一致。

扩展学习

  • 打包发布:深入学习 electron-builder 配置,打包为 Windows、macOS 和 Linux 可执行文件。
  • Vue 高级功能:探索 Vue Router、Vuex 或 Pinia 集成复杂应用。
  • Electron 高级功能:学习系统托盘、菜单栏、自动更新等。
  • 文档资源:参考 Electron 官方文档Vue 官方文档.
  • 社区支持:加入 Electron 和 Vue 的 GitHub Discussions 或 Stack Overflow 社区。

总结

通过本教程,您已经:

  1. 理解了 Electron 的主进程和渲染进程的工作原理。
  2. 掌握了进程间通信(IPC)与 Vue 的集成。
  3. 完成了第一个 Electron + Vue 应用,包含窗口管理和文件选择功能。
  4. 了解了开发中的安全性和常见问题。

继续实践和探索,您将能够构建更复杂的桌面应用!如果有问题,请参考官方文档或社区资源。