vue项目改electron

vue环境

vue
^3.2.31
vite
^2.8.3
electron
^17.0.1
concurrently
^7.0.0
electron-builder
^22.14.5

安装依赖

yarn add -D  cross-env  #解决环境变量
yarn add -D wait-on #延迟加载 监听作用
yarn add -D electron 
yarn add -D  concurrently
yarn add -D  electron-builder #打包工具

# 或者这种方式
yarn add -D cross-env wait-on electron@17.0.1 electron-builder@23.0.3  concurrently

1
2
3
4
5
6
7
8
9

修改前目录结构

这是正常vue的目录结构

|—— dist                     # 打包路径
|—— public                   # 公共文件
|—— scr                      # 源代码
|—— package.json              
1
2
3
4

修改后目录结构

这是正常vue的目录结构

|—— dist                     # 打包路径
|—— electron                 # 配置文件 以及入口文件
|   |—— main.js              # 入口文件
|   |—— preload.js           # api接口注入预加载文件
|—— public                   # 公共文件
|—— scr                      # 源代码
|—— package.json          
|—— electron-builder.json    # 打包配置文件      
1
2
3
4
5
6
7
8

新增文件

main.js

// main.js

// 控制应用生命周期和创建原生浏览器窗口的模组
const { app, BrowserWindow, ipcMain,dialog } = require('electron')
const path = require('path')
const NODE_ENV = process.env.NODE_ENV
function createWindow() {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

    // 加载 index.html
    mainWindow.loadURL(
      NODE_ENV === 'development'
        ? 'http://localhost:3003'
        :`file://${path.join(__dirname, '../dist/index.html')}`
    );
  
    // 打开开发工具
    if (NODE_ENV === "development") {
      mainWindow.webContents.openDevTools()
    }
}

const iconName = path.join(__dirname, '/public/drag-and-drop.png');
// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口
ipcMain.on('ondragstart', (event, filePath) => {
  console.log('filePath :>> ', filePath);
  event.sender.startDrag({
    file: path.join(__dirname, filePath),
    icon: iconName,
  })
})
ipcMain.on('open-directory-dialog', function (event, p) {

  dialog.showOpenDialog({

    properties: [p]

  })
  .then(result=>{
    event.sender.send('selectedItem', result.filePaths[0])
  })

});
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
  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()
})

// 在这个文件中,你可以包含应用程序剩余的所有部分的代码,
// 也可以拆分成几个文件,然后用 require 导入。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

preload.js

const { contextBridge, ipcRenderer} = require('electron')
const path = require('path')
const fs = require('fs')
window.addEventListener('DOMContentLoaded', () => {
    const replaceText = (selector, text) => {
      const element = document.getElementById(selector)
      if (element) element.innerText = text
    }
  
    for (const dependency of ['chrome', 'node', 'electron']) {
      replaceText(`${dependency}-version`, process.versions[dependency])
    }
  })
1
2
3
4
5
6
7
8
9
10
11
12
13

electron-builder.json

不要使用中文

 {  // electron-builder配置
    "productName":"xxxx",//项目名 这也是生成的exe文件的前缀名
    "appId": "xxxxx",//包名  
    "copyright":"xxxx",//版权  信息
    "compression": "store", // "store" | "normal"| "maximum" 打包压缩情况(store 相对较快),store 39749kb, maximum 39186kb
    "directories": {
        "output": "build" // 输出文件夹
    }, 
    "asar": false, // asar打包
    "extraResources":  { // 拷贝dll等静态文件到指定位置
        "from": "./app-update.yml",
        "to": "./b.txt"
    },
    "win": {  
        "icon": "xxx/icon.ico"//图标路径,
        "extraResources":  { // 拷贝dll等静态文件到指定位置(用于某个系统配置)
            "from": "./app-update.yml",
            "to": "./b.txt"
        }
    },
    "nsis": {
        "oneClick": false, // 一键安装
        "guid": "xxxx", //注册表名字,不推荐修改
        "perMachine": true, // 是否开启安装时权限限制(此电脑或当前用户)
        "allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
        "allowToChangeInstallationDirectory": true, // 允许修改安装目录
        "installerIcon": "./build/icons/aaa.ico", // 安装图标
        "uninstallerIcon": "./build/icons/bbb.ico", //卸载图标
        "installerHeaderIcon": "./build/icons/aaa.ico", // 安装时头部图标
        "createDesktopShortcut": true, // 创建桌面图标
        "createStartMenuShortcut": true, // 创建开始菜单图标
        "shortcutName": "xxxx" // 图标名称
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

修改 package.json

 "main": "electron/main.js",//新增内容 这个是新建的main.js 路径
 "scripts": {
   "dev": "vite",
    "build": "vite build",
    "serve": "vite preview",
    "electron": "wait-on tcp:3003 && cross-env NODE_ENV=development electron .",
    "electron:serve": "concurrently -k \"yarn dev\" \"yarn electron\"",
    "electron:build": "vite build && electron-builder",
    "electron-builder": "electron-builder"
  },
1
2
3
4
5
6
7
8
9
10

注意事项

  1. main.js

mainWindow.loadURL("http://localhost:3000/") 3000端口与配置文件保持一致

  1. 建议 vite.config.ts 端口配置一个不冲突的端口

案例地址

案例地址open in new window

源码 分支切换到 electron