【前端小记】Vite集成Vue3+Electron

92 阅读5分钟

前序

因项目需要开发一款基于Electron的叫号屏,所以简单了解了下Vite+Electron的集成流程,在此作为笔记记录下来。

Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。

Vite(法语意为 "快速的",发音 /vit/,发音同 "veet")是一种新型前端构建工具,能够显著提升前端开发体验。它主要由两部分组成:

依赖

Vite vite@latest(^7.2.4)
Electron electron@latest(^39.2.7)
Vite-Electron插件 vite-plugin-electron@0.29.0
Vue vue@3.x

安装

  1. 创建Vite最新项目
使用npm
$ npm create vite@latest
或使用yarn
$ yarn create vite
  1. 运行vite
npm run dev

VITE v7.3.0  ready in 441 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

看到控制台输出日志后,访问5173端口,表示vite集成vue3依赖正常安装运行。

image.png

  1. 安装Electron及Vite-Electron插件
# 安装Electron
npm i electron -D

# 安装vite-electron插件
npm i vite-plugin-electron -D
  1. 添加Electron配置到项目根目录中的vite.config.js文件
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// 添加
import electron from 'vite-plugin-electron/simple'

// https://vite.dev/config/
export default defineConfig({
  plugins: [vue(),
    // 添加
    // 插件仓库地址:https://github.com/electron-vite/vite-plugin-electron
    electron({
      main: {
        // Shortcut of `build.lib.entry`
        entry: 'electron/main.js',
      },
      preload: {
        // Shortcut of `build.rollupOptions.input`
        input: 'electron/preload.js',
      },
      // 此行需注释,因为没有安装
      //renderer: {},
    })
  ],
})
  1. 在对应的目录地址下创建main和preload读取的文件,以上面为例在vite.config.js同级目录下创建文件夹electron,并添加子文件main.js和preload.js
vite-project
|--electron
|--|--main.js
|--|--preload.js
|-- ...
|--vite.config.js
  1. 编辑electron/main.js
import { app, BrowserWindow } from 'electron'

app.whenReady().then(() => {
  const win = new BrowserWindow({
    title: 'Main window',
  })

  // You can use `process.env.VITE_DEV_SERVER_URL` when the vite command is called `serve`
  if (process.env.VITE_DEV_SERVER_URL) {
    win.loadURL(process.env.VITE_DEV_SERVER_URL)
  } else {
    // Load your file
    win.loadFile('dist/index.html');
  }
})
  1. 测试环境是否正常
# 运行项目
npm run dev

首次运行会产生一个找不到electron app的弹窗

image.png

此时在项目根目录会自动生成一个dist-electron目录,证明安装electron以及vite插件正常。

编辑package.json文件,删除type属性,添加main属性。

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "main": "dist-electron/main.js",

  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.5.24"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^6.0.1",
    "electron": "^39.2.7",
    "vite": "^7.2.4",
    "vite-plugin-electron": "^0.29.0"
  }
}

保存后重新执行运行命令。

# 运行项目
npm run dev

弹窗显示vite+Vue图标页面表示正常运行Electron+Vue3。

image.png

  1. 安装Vue-router并改造页面支持路由
# 安装依赖
npm install vue-router@4

新建src/route/index.js文件,并新增以下内容

import { createRouter, createWebHistory } from 'vue-router'
const routes = [
  // 测试用,替换成你的实际页面
  { path: '/', component: () => import('@/Test.vue') }
]

export default createRouter({
  history: createWebHistory(),routes
})

修改src/main.js,注意不要修改成electron/main.js文件了

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 修改
import router from './route'
const app =createApp(App)
app.use(router)
app.mount('#app')

在src下创建一个Test.vue文件进行验证。

<template>
  <div>Test</div>
</template>

修改App.vue文件

<script setup>
</script>

<template>
  <router-view/>
</template>

<style scoped>
#app {
    text-align: center;
  }
</style>

运行查看窗口是否显示Test字符串,显示则为成功。

image.png

调用ElectronAPI

前文我们安装好了vue+vue-router环境,可以正常按照想要的业务逻辑按照axios进行网络间通信。

如果我们需要在这个桌面应用中调用Electron提供的一些API(例如系统打印、退出、快捷键绑定等功能),需要回到electron/main,js、electron/preload,js两个文件中。

【为方便,下文提及main.js、preload.js均指代Electron目录下的文件】

修改main.js

import { app, BrowserWindow } from 'electron'
import path from 'path'
const __dirname = path.dirname(__filename)
// 文档:https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-first-app
// API文档:https://www.electronjs.org/zh/docs/latest/api/browser-window#class-browserwindow-extends-basewindow
// 在应用准备就绪时调用函数
app.whenReady().then(() => {
  // 创建窗口
  const win = new BrowserWindow({
    title: 'Main window',
    // 网页功能设置
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),  // 预加载脚本地址,需要绝对路径
      contextIsolation: true, // 上下文隔离
      nodeIntegration: false, // 是否启用Node.js
    }
  })

  // You can use `process.env.VITE_DEV_SERVER_URL` when the vite command is called `serve`
  if (process.env.VITE_DEV_SERVER_URL) {
    win.loadURL(process.env.VITE_DEV_SERVER_URL)
  } else {
    // Load your file
    win.loadFile('dist/index.html');
  }
})

修改Preload.js

import {contextBridge, ipcRenderer} from 'electron'

// 将渲染进程的API暴露给主进程, 第一个参数为暴露的API名称, 第二个参数为暴露的API实现
contextBridge.exposeInMainWorld('electronAPI', {
  
})
  1. 测试从Test.vue文件中调用Electron的退出应用API

在main.js中监听退出方法

// 修改
import { app, BrowserWindow, ipcMain, dialog } from 'electron'

app.whenReady().then(() => {
    ...与上文相同省略
  // 添加
  ipcMain.handle('test-quit', () => {
    dialog.showMessageBox({
      type: 'info',
      title: '提示',
      message: '确定要退出吗?',
      buttons: ['确定', '取消']
    }).then(result => {
      if (result.response === 0) {
        app.quit()
      }
    })
  })
})

修改preload.js中的暴露内容

contextBridge.exposeInMainWorld('electronAPI', {
    // 将testQuit暴露到MainWorld中
  testQuit: () => ipcRenderer.invoke('test-quit')
})

到Test.vue中调用,Test.vue修改后的内容如下。

<template>
  <div>
    <div>Test</div>
    <button @click="handleTest">测试Electron退出API</button>
  </div>
</template>

<script setup>
  const handleTest = () => {
    window.electronAPI.testQuit()
  }
</script>

运行项目,点击按钮出现系统弹窗说明调用成功。

image.png

image.png

小结

由于篇幅有限,加上很多东西笔者都是现学的,因此本文在此对于Electron属于浅尝即止,更多的东西还需要各位读者亲自到文档中和亲身体验中学习领略,如果文章对您有所帮助,请点下免费的赞和关注,后续让我们一起进步。