Electron+Vue3+Vite的产品级模板项目

1. electron-vue3-template

基于Vue3 + Electron + TypeScript的客户端程序模板,使用ViteElectron Forge构建和打包。

真正做到开箱即用,面向跨平台客户端设计,产品级的项目模板。

项目地址:
https://github.com/winsoft666/electron-vue3-template

请添加图片描述

1.1 特性

  • 使用ViteJS构建和驱动前端页面,支持热加载(HMR),使开发和调试变得更加高效 ⚡
  • 支持Vue3多页面,提供页面创建指令,适合客户端开发场景 💖
  • 支持Electron窗口创建指令,并且可隔离不同窗口的IPC事件 💖
  • 封装简化了IPC的调用方式,并提供了IPC函数快速创建指令,主进程与渲染进程的相互调用从未如此简单 👍
  • 主进程和渲染进程支持热加载 ⚡
  • 精选依赖包,提升项目稳定性
  • 代码简洁,易掌控,可定制性强
  • 日志文件,主进程和渲染进程可以直接写文件日志
  • 配置文件
  • 文件下载(含哈希校验、进度反馈),渲染进程可直接异步调用 👍
  • 功能完善的无边框窗口
  • 托盘图标和右键菜单,窗口关闭时程序最小化到托盘
  • 客户端程序单实例
  • 基于ESLint的代码规范和自动格式化
  • 使用Electron官方推荐的Electron Forge进行客户端构建和打包
  • 支持NSIS安装包 😎

1.2 快速开始 🌈

点击右上角绿色的 Use this template 按钮,使用该模板创建一个新的仓库并克隆到本地。

或者…

直接克隆该项目: git clone https://github.com/winsoft666/electron-vue3-template.git

Visual Studio Code

推荐使用Visual Studio Code进行项目开发,并安装如下插件:

  • ESLint
  • Vue Language Features (Volar)

安装依赖 ⏬

yarn install

开发 ⚒️

yarn run dev

其他命令

yarn run dev # 启动应用并支持热加载
yarn run build # 构建应用,可发布的包位于"out\make"目录

# 或者
yarn run build:win32 # 构建Windows平台 32位应用
yarn run build:win64 # 构建Windows平台 64位应用
yarn run build:mac # 构建macOS平台应用
yarn run build:linux # 构建Linux平台应用

yarn run new:page  # 创建新的Vue页面
yarn run new:window # 创建新的Electron窗口

更多的可选配置项可以参考 Electron Forge CLI docs。

NSIS安装包 🪟

需要先手动下载和安装NSIS:
https://nsis.sourceforge.io/Download

使用如下命令构建Windows平台 32位应用(如需构建64位应用,则需要手动修改win-setup-x86.nsi脚本):

yarn run build:win32

运行NSIS安装目录内的makensisw.exe

依次点击File -> Load Script...,选择并加载本项目的setup\NSIS\win-setup-x86.nsi脚本。

最后,执行Recompile命令即可编译生成安装包。

请添加图片描述

2. 项目介绍

2.1 工程结构 🌳

- scripts/         # 该目录中的脚本用构建应用程序和驱动前端页面
- screenshots      # 本文档中用到的截图
- setup/            # 存储编译和构建相关文件
  - NSIS/                # NSIS安装包脚本
  - exe.ico             # 构建后的可执行文件图标(非安装包图标)
  - install.ico        # NSIS安装包图标
  - uninstall.ico      # NSIS卸载程序图标
- src/
  - lib/            # 公共库,为了方便修改,未做成独立的包
    - file-download/    # 文件下载库
      - main                 # 仅供主进程使用
      - renderer            # 仅供渲染进程使用
      - shared               # 主进程和渲染进程都可以使用
    - utils/            # 公共代码库
  - main/           # 主进程的代码 (Electron)
    - static/          # 静态资源
    - windows/         # 多窗口文件夹 (每个子目录表示一个窗口)
      - primary/          # 主窗口(客户端通常都会有一个主窗口)
      - frameless/        # 无边框示例窗口
      - ...
  - renderer/      # 渲染进程的代码 (VueJS)
    - public           # 静态资源
    - pages/           # 多页面目录 (强制约定:每个子目录代表一个页面)
      - primary/          # 主窗口页面
      - frameless/        # 无边框示例窗口的页面
      - ...
    - typings/         # ts声明文件

2.2 使用静态文件

  • src/main/static目录存放主进程使用的静态文件。
  • src/renderer/public目录存放渲染进程使用的静态文件。
在主进程中引用静态文件
// 假设 src/main/static/tray.ico 文件存在
// 使用 appState.mainStaticPath 属性获取主进程的静态文件存储目录
import path from "path";
import appState from "./app-state";

const iconPath = path.join(appState.mainStaticPath, "tray.ico");

2.3 AppState对象

为了方便在主进程中跨模块访问某些对象(如primaryWindowtraycfgStore等)和应用配置(如onlyAllowSingleInstance等),我们定义了单实例对象AppState来存储这些数据。

使用方法如下:

import appState from "./app-state";

appState.primaryWindow?.show();

2.4 快速创建Vue页面

执行如下命令,输入页面名称后将自动在renderer/pages目录创建子页面,每个子页面的相关代码位于单独的目录中,目录名为我们指定的页面名称(小写)。

yarn run new:page

创建的子页面在代码中通过以下方式访问:

// 开发环境
const rendererPort = process.argv[2];
primaryWindow.loadURL(`http://localhost:${rendererPort}/pages/<PAGE-NAME>/index.html`);

// 非开发环境
primaryWindow.loadFile(path.join(app.getAppPath(), "build/renderer/pages/<PAGE-NAME>/index.html"));

2.5 快速创建Electron窗口

虽然直接构造Electron的BrowerWindow对象就可以创建新的Electron窗口,但为了方便代码管理和ipcMain消息隔离,本模板中的每个窗口都继承自WindowBase对象,每个窗口的相关代码位于src\main\windows\的不同子目录中,目录名为我们指定的窗口名称(小写)。

yarn run new:window

创建的子窗口默认会访问同名的子页面,可以手动修改代码访问其他页面:

if(process.env.NODE_ENV === "development"){
  const rendererPort = process.argv[2];
  primaryWindow.loadURL(`http://localhost:${rendererPort}/pages/primary/index.html`);
}else{
  primaryWindow.loadFile(path.join(app.getAppPath(), "build/renderer/pages/primary/index.html"));
}

创建窗口后,需要在registerIpcMainHandler方法中注册该窗口的ipcMain事件及处理函数。

如果多个窗口注册了同名的事件,当渲染进程发送该名称的事件到主进程时,所有窗口对象都会收到该事件,为了避免这种情况,我们可以在事件处理函数中使用isIpcMainEventBelongMe方法来过滤非本窗口的事件。

ipcMain.on("message", (event, message) => {
  if(!this.isIpcMainEventBelongMe(event))
    return;

  console.log(message);
});

2.6 快速创建IPC函数

src\renderer\pages\primary\App.vue中获取文件MD5的代码如下:

async function onGetFileMd5(){
  const result = await utils.showOpenDialog({
    properties: [ "openFile" ],
    filters: [
      { name: "All Files", extensions: [ "*" ] }
    ]
  });

  if(result.filePaths.length > 0){
    utils.getFileMd5(result.filePaths[0])
      .then((md5) => {
        message.success(md5);
      }).catch((e) => {
        message.error(GetErrorMessage(e));
      });
  }
}

上述代码通过调用Utils库的showOpenDialoggetFileMd5函数轻松实现了通知主进程选择文件、计算文件MD5并获取相应结果的操作,代码非常简洁。

但是Utils只预置了部分常用的功能,预置功能肯定无法满足我们产品开发的所有需求。在此情况下,我们可以向Utils库中添加自定义的功能函数,该如何添加了?

不用担心,本模板已经提供了IPC函数快速创建指令:

yarn run new:ipc

执行上面指令后,会出现如下提示:

Create syntax: CallWay,FunctionName,FunctionType
Call Way:
        rm = Renderer process call the function of main process
        mr = Main process call the function of renderer process (Ignore FunctionType)
Function Name:
        xxx-xxx-xxx
Function Type:
        a = Asynchronous call without result
        ap = Asynchronous call with promise result
        s = Synchronous call with result

参数1(CallWay)表示函数调用方向:

  • rm 表示渲染进程调用主进程的函数,可以支持同步调用、异步调用,并且可以返回Promise结果。
  • mr 表示主进程调用渲染进程的函数,该方向只能是异步调用,而且不支持返回结果,会忽略第三个参数(FunctionType)。

参数2(FunctionName)表示函数名称,函数名称的单词间使用-分隔,如GetFileSha256需要指定为get-file-sha256

参数3(FunctionType)函数类型:

  • a 表示不返回结果的异步函数
  • ap 表示返回Promise结果的异步函数
  • s 表示同步函数

示例

依次输入如下命令:

yarn run new:ipc

Input:
rm,get-file-sha256,ap

命令执行成功后,会自动在src\lib\utils\renderer\index.ts生成Utils.getFileSha256函数:

public async getFileSha256(){
  return await (window as any).__ElectronUtils__.getFileSha256();
}

自动生成的函数都没有指定参数和返回值,需要我们手动添加,如修改后的函数如下:

public async getFileSha256(filePath: string) : string {
  return await (window as any).__ElectronUtils__.getFileSha256(filePath) as string;
}

在渲染进程中(如App.vue)中可以直接调用该函数:

import utils from "../../../lib/utils/renderer";

const sha256 = await utils.getFileSha256("file-path.txt");

IPC函数创建指令只会创建函数骨架,不会为我们实现具体的功能,我们还需要在主进程ipcMain处理函数中实现计算文件SHA256的具体功能。

自动生成的主进程ipcMain处理函数如下:

ipcMain.handle("electron-utils-get-file-sha256", async(event) => {
});

手动添加参数、返回值,及具体的功能代码(此处省略):

ipcMain.handle("electron-utils-get-file-sha256", async(event, filePath: string) : Promise<string> => {
  // .....
});

3. 代码规范

本项目使用ESLint进行代码检查和格式化,没有使用Prettier进行代码格式化。

原因大体如下:

  1. 需要额外的插件和配置来避免ESLint和Prettier的规则冲突。

  2. Prettier的printWidth配置项会损害代码和Git Diff的可读性。
    请添加图片描述
    请添加图片描述

在线演示

4. 依赖包 🎈

4.1 基本原则

一个构建在众多不稳定性因素下的项目,是没有稳定性可言的。

为了保证项目的稳定性,本模板项目只使用具有知名度、稳定性强的依赖包(库),如electron-log等。

对于作者自己写的库(如file-download等),统一以源码形式提供在src\lib\目录,方便模板使用者进行bug修复和功能扩充,在使用时直接采用相对路径进行导入即可。

4.2 dependencies和devDependencies的区别

由于Electron Forge会将dependencies中的所有依赖项都进行打包,因此为了减少安装包的体积,我们只将主进程需要使用的依赖安装到dependencies项下,而其他的依赖均安装到devDependencies

如将vue作为开发依赖进行安装:

yarn add -D vue

4.3 依赖包说明

作为开发者,应知晓每个依赖包的用途,避免node_modules黑洞的产生。

  • unplugin-vue-components
    实现自动按需引入AntDesign-Vue组件。

  • electron-log
    提供本地日志文件的打印和输出。

  • electron-store
    提供本地配置文件的读取和写入功能。

  • @fortawesome-*
    提供对FontAwesome图标字体的支持。

  • uuid
    使用uuid字符串,在file-download库中使用。

  • chalk
    用于在命令行终端输出带颜色样式的字符串,仅在scripts\*.js中使用。

  • chokidar
    轻量级的文件监控组件,用于实现热加载,仅在scripts\*.js中使用。

  • @electron-forge/*
    与Electron Forge构建和打包相关的依赖包,除了@electron-forge/cli是必须的,其他的可以根据forge.config.js -> makers的配置按需引用。

5. 客户端版本号

使用package.json文件的version字段标识客户端的版本号,在主进程内可以通过appState.appVersion属性获取。

💡 不需要设置forge.config.js文件的appVersion字段。

在渲染进程可以直接使用utils.getAppVersion()获取版本号。

import utils from "../../../lib/utils/renderer";

console.log(utils.getAppVersion());

6. 期待你的反馈 🥳

个人能力有限,代码不免有错误和不足之处,欢迎提交issue和PR。

如果这个项目对你有帮助,无需捐助,点击右上角Star ⭐让我知道就可以了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/367306.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Golang `crypto/hmac` 实战指南:代码示例与最佳实践

Golang crypto/hmac 实战指南&#xff1a;代码示例与最佳实践 引言HMAC 的基础知识1. HMAC 的工作原理2. HMAC 的应用场景 Golang crypto/hmac 库概览1. 导入和基本用法2. HMAC 的生成和验证3. crypto/hmac 的特性 实战代码示例示例 1: 基本的 HMAC 生成示例 2: 验证消息完整性…

C++通用编程(2)

函数模板高级用法 1.分文件编写的优点2.普通函数的分文件编写3.函数模板的分文件编写4.细节提示5.函数模板应用高级decltype推导类型函数后置返回类型 6.总结 函数模板讲完后&#xff0c;C全部的函数类型我们就接触的差不多了。今天给做一些关于函数份文件编写的知识点补充。 1…

C语言问题汇总

指针 #include <stdio.h>int main(void){int a[4] {1,2,3,4};int *p &a1;int *p1 a1;printf("%#x,%#x",p[-1],*p1);} 以上代码中存在错误。 int *p &a1; 错误1&#xff1a;取a数组的地址&#xff0c;然后1&#xff0c;即指针跳过int [4]大小的字节…

调试以及发布npm组件

开发原因&#xff1a; 由于公司自己的封装到npm的组件有点问题&#xff0c;负责人由在忙其他&#xff0c;就由我去负责改改&#xff0c;中途出了不少问题&#xff0c;记录一下。 一、下载源码 第一步肯定是去git上把组件的源码下载下来&#xff0c;这一步没什么好说&#xf…

日志记录——单片机可执行文件合并

一&#xff1a;需求场景 现在有一片单片机&#xff0c;执行程序包括自定义boot和应用程序app, 在将打包好的固件给到生产是有以下问题&#xff0c;由于要通过jlink烧录boot&#xff0c;然后上电启动boot&#xff0c;通过boot烧录初始化程序&#xff0c;过程过于复杂&#xff0…

Oracle和Mysql数据库

数据库 Oracle 体系结构与基本概念体系结构基本概念表空间(users)和数据文件段、区、块Oracle数据库的基本元素 Oracle数据库启动和关闭Oracle数据库启动Oracle数据库关闭 Sqlplussqlplus 登录数据库管理系统使用sqlplus登录Oracle数据库远程登录解锁用户修改用户密码查看当前语…

嵌入式软件中常见的 8 种数据结构

数据结构是一种特殊的组织和存储数据的方式&#xff0c;可以使我们可以更高效地对存储的数据执行操作。数据结构在计算机科学和软件工程领域具有广泛而多样的用途。 几乎所有已开发的程序或软件系统都使用数据结构。此外&#xff0c;数据结构属于计算机科学和软件工程的基础。当…

SpringBoot:@Profile注解和Spring EL

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Prof…

业务流程自动化平台在制造业应用案例,助力业务自动化、智能化

捷昌驱动成立于2000年&#xff0c;并于2018年9月在上海证券交易所上市&#xff0c;是一家专注于线性驱动产品研发、生产及销售的科技集团。 公司整合全球资源&#xff0c;为智慧办公、医疗康护、智能家居、工业自动化等关联产业提供驱动及智能控制解决方案&#xff0c;以科技驱…

Linux系统安全:安全技术 和 防火墙

一、安全技术 入侵检测系统&#xff08;Intrusion Detection Systems&#xff09;&#xff1a;特点是不阻断任何网络访问&#xff0c;量化、定位来自内外网络的威胁情况&#xff0c;主要以提供报警和事后监督为主&#xff0c;提供有针对性的指导措施和安全决策依据,类 似于监控…

Sentinel安装

1、下载 sentinel官方提供了UI控制台&#xff0c;方便我们对系统做限流设置。大家可以在GitHub下载。 2、运行 将jar包放到任意非中文目录&#xff0c;执行命令&#xff1a; java -jar sentinel-dashboard-1.8.1.jar 如果要修改Sentinel的默认端口、账户、密码&#xff0c;…

【unity小技巧】unity3d环境带雾的昼夜系统变化

最终效果 文章目录 最终效果眩光素材眩光配置全局灯光配置天空盒配置天空盒资产配置天空盒&#xff0c;开启雾 代码控制天空盒 环境 雾 灯光昼夜交替变化参考完结 眩光素材 链接&#xff1a;https://pan.baidu.com/s/1qlFSJSju6ZjwCylwkh14eA?pwdveww 提取码&#xff1a;veww…

面试150 二进制求和 位运算

Problem: 67. 二进制求和 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 参考 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) Code class Solution {public String addBinary(String a, String b){StringBuilder ans new Stri…

【知识点】Java多线程

文章目录 线程基础happen-before规则基础概念线程方法线程状态转换状态控制参考链接 线程应用线程安全常用锁独享锁 VS 共享锁自旋锁可重入锁 VS 非可重入锁锁的状态无锁偏向锁轻量级锁重量级锁综述 公平锁非公平锁同步锁乐观锁悲观锁对比 AQS基础说明原理概览常用方法应用场景…

Java 基于 SpringBoot+Vue 的考研论坛管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

十分钟上手vue!

Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;Vue 都可以胜任。 一 vue.js的导入及使用 vue安装…

【Boost】:parser代码的基本结构(二)

parser代码的基本结构 一.总体概述二. EumeFile的实现三.ParserHtml的实现四.SaveHtml实现五.完整源代码 打开parser.cc,用vscode或者vim都行。 一.总体概述 首先递归式的把文件名和路径读入一个数组内&#xff0c;接着把数组内的每一个数据按照一定的格式进行划分&#xff0c;…

云原生业务全流程DevOps配置预研与实践

背景 我在一个二线城市&#xff08;山东济南&#xff09;&#xff0c;相对与北上广深杭这些IT业发达的城市来说&#xff0c;济南IT业对于业内新技术的接受度是有点慢的&#xff0c;国内很多一线大厂早先几年前就开始实践使用的技术&#xff0c;我们这边也是近两年才开始慢慢兴…

10. BI - 决策树的使用及可视化

本文为 「茶桁的 AI 秘籍 - BI 篇 第 10 篇」 文章目录 可视化探索决策树原理决策树算法决策树可视化泰坦尼克海难数据 Hi&#xff0c;你好。我是茶桁。 上一节课&#xff0c;咱们了解了图形的具体绘制方法&#xff0c;接下来咱们还要看看除了图形绘制之外&#xff0c;还有哪些…

手把手教你开发Python桌面应用-PyQt6图书管理系统-主界面UI背景及状态栏代码设置

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…