手把手教你如何新建一个vue3+electron项目

一、使用npm creat vite@latest创建一个vue3项目

npm creat vite@latest

在这里插入图片描述
并且运行提示的这几个步骤
在这里插入图片描述

二、加入electron

electron官方文档:https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-first-app

1、安装依赖

npm install electron --save-dev

2、创建electron的主入口文件以及添加运行脚本命令

在package.json中增加main告诉electron的主入口文件:

添加electron的运行命令为 : npm run start
在这里插入图片描述
创建main.js文件,并写入以下代码(官网代码):

const {
    
     app, BrowserWindow } = require('electron')

const createWindow = () => {
    
    
  const win = new BrowserWindow({
    
    
    width: 800,
    height: 600
  })

  // win.loadFile('index.html')
  
  // 下面的url为自己启动vite项目的url。
  win.loadURL('http://127.0.0.1:5173/')
  // 打开electron的开发者工具
  win.webContents.openDevTools({
    
     mode: 'detach' })
}

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

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

运行npm run start就能成功的运行起你的第一个electron项目了。

npm run start

在这里插入图片描述
注意,此时你的vite项目应该也是要在运行状态下的,win.loadURL(‘http://127.0.0.1:5173/’)),其中的url就是你运行vite项目的url。相当于此时我们运行了两个项目,一个是electron项目,一个是vite的项目,然后electron相当于就是一个window/mac窗口,然后把网址塞到了这个窗口里面。后期上线就是把开发时的url地址换成已经上线的url地址就行了
在这里插入图片描述
在这里插入图片描述
此时会有一个报错:
原因:是electron安全策略的设置告警,意思是内容安全策略没有设置,或者使用了unsafe-eval的安全设置

参考解决方法:https://blog.csdn.net/hwytree/article/details/121287531

在这里插入图片描述
到index.html里面加一行

<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline';">

就解决了

三、加入electron预加载脚本,并通过其进行electron和vue的交互

注意:这里你一定要深刻理解这个预加载脚本的作用,否则你会对这个预加载脚本感到很疑惑。这里解释一下这个预加载脚本的作用。

概念理解:
主进程:指的是你的electron进程
预加载脚本:electron进程与vue项目通信的直接桥梁
渲染进程:就是你的vue项目或者react项目

根据electron官网(https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-preload)所说的,为了安全以及隔离环境,渲染进程与主进程之间的通信需要通过一个preload.js来进行。(总的来说这个preload.js的作用就是作为渲染进程与主进程之间的通信桥梁,做的事就是:

  1. 给渲染进程(可以说是你src下面的.vue文件和.js文件)暴露方法供渲染进程调用
  2. 渲染进程调用该方法,该方法中可以给主进程发送事件,然后在主进程中一般会监听该事件,再调用electron的api来改变应用的状态(比如改变窗口的外壳大小,让窗口最小化)

1、在src同级目录建立preload文件夹,下面写index.js,加入以下代码:

在这里插入图片描述
preload/index.js

const {
    
     contextBridge, ipcRenderer } = require('electron')
const handleSend = async (vue_params) => {
    
    
  let fallback = await ipcRenderer.invoke('sent-event', vue_params)
  return fallback
}
contextBridge.exposeInMainWorld('myApi', {
    
    
  handleSend: handleSend
  // 能暴露的不仅仅是函数,我们还可以暴露变量
})

2、在main.js中引入预加载脚本,并且添加主进程的监听事件:

webPreferences: {
    
    
	preload: path.join(__dirname, './preload/index.js')
}
ipcMain.handle('sent-event', (event,params) => {
    
    
  console.log(params)
  return '1111'
})

在这里插入图片描述

3、在vue中调用,可以看到主进程给我们返回的结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
说明:这里主要是告诉大家怎么去引入electron的预加载脚本以及一个简单的使用。具体的通信过程大家可以参考两篇文章:
https://blog.csdn.net/weixin_44582045/article/details/128564789
https://blog.csdn.net/weixin_43239880/article/details/129563632
官网教程

4、处理ts的报错:在env.d.ts中加入以下代码:

在这里插入图片描述
此时我们已经成功的创建了一个vite+vue3+ts+electron的项目!!!

四、优化开发体验

因为此时我们修改vue代码,vite会帮我们热重启。但是当我们修改electron文件的代码时,并没有脚手架帮我们热重启,所以此时我们需要添加nodemon,帮我们重启一下。

1、安装nodemon依赖:

npm i nodemon -D

在package.json中的scripts添加这句进行启动electron项目,nodemon在检测到有以.js,.html结尾文件发生变动时,就会重启窗口
(如果需要改变.vue和.css的时候同时启动,也可以继续往后面加,但是没必要,因为这些文件改变,vite会自动热重启。)

"start": "nodemon --exec electron . --watch ./ --ext .js,.html"

在这里插入图片描述

五、为vite项目添加一些开发必备的工具

如:添加commitLint,加入element-plus,配置别名,配置代理,添加axios及封装,添加pinia等
如何添加请查看这篇文章,每一步都有详细的步骤和用法。这里就不细说了。

六、添加系統托盘

基本上的桌面端项目都有托盘,所以这里也就写出来了一个简易版本的。大家可以参考一下:
在这里插入图片描述

1、在src同级目录新建一个controller目录,在里面建一个tray.js文件

在这里插入图片描述

// 创建系统托盘
const {
    
     Tray, Menu } = require('electron')

const path = require('path')

function createTray (app, win) {
    
    
  let tray = new Tray(path.join(__dirname, '../public/favicon.ico'))
  tray.setToolTip('electron_vue_demo') // 鼠标放在托盘图标上的提示信息

  tray.on('click', (e) => {
    
    
    if (e.shiftKey) {
    
    
      app.quit()
    } else {
    
    
      win.show()
    }
  })
  tray.setContextMenu(
    Menu.buildFromTemplate([
      {
    
    
        label: '退出',
        click: () => {
    
    
          // 先把用户的登录状态和用户的登录信息给清楚掉,再退出
          app.quit()
        }
      }
    ])
  )
}

module.exports = createTray

2、在main.js中导入并且使用改函数用来创建托盘

在这里插入图片描述

七、自定义窗口(不使用原生的窗口)

在这里插入图片描述

原生的窗口不好看,很难看。且无法去修改,导致满足不了UI的效果,所以很多桌面程序都是自定义窗口。
这里主要是在main.js中创建窗口的时候加入。
在这里插入图片描述

const win = new BrowserWindow({
    
    
  width: 800,
  height: 600,
  frame: false, // 不要自带的窗口
  webPreferences: {
    
    
    preload: path.join(__dirname, './preload/index.js')
  }
})

具体其它配置,可以看这里https://www.bookstack.cn/read/electron-zh/28.md

然后想实现一个这样的 DIY一个
在这里插入图片描述

1、在HomeView.vue中修改样式

<template>
  <main>
    <div class="hearder">
      <span @click="toMin">最小化</span>
      <span @click="toBig">最大化</span>
      <span @click="toClose">关闭</span>
    </div>
    <div class="main">主要内容</div>
    <!-- <TheWelcome /> -->
  </main>
</template>

<script setup lang="ts">
import {
    
     onMounted } from 'vue'
// import TheWelcome from '../components/TheWelcome.vue'

onMounted(async () => {
    
    
  let res = await window.myApi.handleSend('zm666 nb')
  console.log(res)
})
const toMin = () => {
    
    
  window.myApi.windowMin()
}
const toBig = () => {
    
    
  window.myApi.windowMax()
}
const toClose = () => {
    
    
  window.myApi.windowClose()
}
</script>


<style scoped>
.hearder {
    
    
  -webkit-app-region: drag; // 添加这个 才可拖动
  background-color: #ccc;
  height: 40px;
  width: 100%;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
.hearder span {
    
    
  margin: 0 16px;
  border: 1px solid rgb(35, 34, 34);
  cursor: pointer;
  -webkit-app-region: no-drag;
}
.main {
    
    
  height: calc(100vh - 40px);
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>

2、再实现按钮的功能

preload/index.js

const {
    
     contextBridge, ipcRenderer } = require('electron')
const handleSend = async (vue_params) => {
    
    
  let fallback = await ipcRenderer.invoke('sent-event', vue_params)
  return fallback
}
contextBridge.exposeInMainWorld('myApi', {
    
    
  handleSend: handleSend,
  // 能暴露的不仅仅是函数,我们还可以暴露变量

  // 最小化
  windowMin: () => {
    
    
    ipcRenderer.send('window-min')
  },
  // 最大化
  windowMax: () => {
    
    
    ipcRenderer.send('window-max')
  },
  // 关闭窗口
  windowClose: () => {
    
    
    ipcRenderer.send('window-close')
  }
})

3、在controller文件夹中创建changeWindowSize.js文件,加入以下代码,并在主进程的main.js中导入

这里的代码,其实就是在主进程中调用electron的事件。因为在渲染进程中无法使用electron的东西,所以需要通过预加载脚本来发送事件,主进程监听到了这个事件并作出了相应的回应。
controller/changeWindowSize.js

const {
    
     ipcMain, BrowserWindow } = require('electron')
// 最小化
ipcMain.on('window-min', event => {
    
    
  const webContent = event.sender
  const win = BrowserWindow.fromWebContents(webContent)
  win.minimize()
})

// 最大化
ipcMain.on('window-max', event => {
    
    
  const webContent = event.sender
  const win = BrowserWindow.fromWebContents(webContent)
  if (win.isMaximized()) {
    
    
    win.restore()
  } else {
    
    
    win.maximize()
  }
})

// 关闭
ipcMain.on('window-close', event => {
    
    
  const webContent = event.sender
  const win = BrowserWindow.fromWebContents(webContent)
  win.close()
})

main.js引入
在这里插入图片描述
一些diy基本功能就实现了

在这里插入图片描述

八、项目打包

1、安装依赖

npm install electron-builder -D

2、在package.json中进行配置

配置项信息具体看官方文档:https://www.electron.build/configuration/configuration
也可以看这篇博客:https://juejin.cn/post/6844903693683261453#comment

我就直接贴我们这边的配置了(这个build和scripts同级)

"build": {
    
    
    "appId": "com.zm666.desktop",//包名  
    "productName": "测试平台", //项目名 这也是生成的exe文件的前缀名
    "asar": true,
    "copyright": "Copyright © 2023 electron",//版权  信息
    "publish": {
    
    
      "provider": "generic",// 服务器提供商 也可以是GitHub等等
      "url": ""// 服务器地址
    },
    "directories": {
    
     // 输出文件夹
      "output": "electron-build/"
    },
    "extraResources": [
      {
    
    
        "from": "./public",
        "to": "./public"
      }
    ],
    "files": [ // 打包的electron需要包含的文件,一般就是与electron的有关的打包进去
      "main.js", // electron主入口文件
      "controller", // 也是主入口文件,只不过拆成了两个文件
      "preload" //预加载文件
    ],
    "mac": {
    
    
      "artifactName": "${productName}_${version}.${ext}",
      "target": [
        "dmg"
      ]
    },
    "win": {
    
    
      "icon": "public/logoTemplate.ico",
      "target": [
        {
    
    
          "target": "nsis",
          "arch": [
            "ia32"
          ]
        }
      ],
      "artifactName": "${productName}_${version}.${ext}"
    },
    "nsis": {
    
    
      "oneClick": false,// 是否一键安装
      "perMachine": false,
      "allowToChangeInstallationDirectory": true,// 允许修改安装目录
      "deleteAppDataOnUninstall": false,
      "installerIcon": "public/favicon.ico",// 安装图标
      "uninstallerIcon": "public/favicon.ico",// 创建桌面图标
      "createDesktopShortcut": true,// 创建桌面图标
      "createStartMenuShortcut": true,// 创建开始菜单图标
      "shortcutName": "zm666测试平台" // 图标名称
    },
    "releaseInfo": {
    
    
      "releaseNotes": "版本更新的具体内容"
    }
  }

3、进行打包,使用命令:npm run app:dist

在package.son中加入运行命令:

"app:dist": "electron-builder"

在这里插入图片描述
打包可能会失败,解决方法:
1、使用科学上网
2、参考这篇文章:https://blog.csdn.net/weixin_43239880/article/details/129532978

在这里插入图片描述
打包好咯
点击exe安装、启动

九、打包vite项目、上线

npm run build

将vite项目打包后的dist文件上线。将main.js中的url改成把上线后的ip地址

十、demo地址

https://github.com/ZhangMin1998/electron_vite_ts_demo

猜你喜欢

转载自blog.csdn.net/weixin_44582045/article/details/133927098