基于 Electron + Vue3 的仿 PC 微信客户端项目实战

目录

一、项目介绍

二、项目结构

1.vscode项目截图:

2.项目依赖

三、项目截图

1.登录页

2.聊天主页

3.好友通讯录

4.设置管理

5.朋友圈

四、源码解析

1.环境准备

2.使用脚手架创建项目

3.主配置文件源码

[3.1 代码逐段解析](#3.1 代码逐段解析)

[3.1.1 模块导入与全局变量](#3.1.1 模块导入与全局变量)

[3.1.2 创建主窗口](#3.1.2 创建主窗口)

[3.1.3 开发模式与窗口事件](#3.1.3 开发模式与窗口事件)

[3.1.4 加载页面资源](#3.1.4 加载页面资源)

[3.1.5 应用就绪与生命周期管理](#3.1.5 应用就绪与生命周期管理)

4.项目依赖

五、总结


一、项目介绍

**摘要:**本文带你快速上手一个基于 Electron + Vue3 仿 PC 微信客户端项目,涵盖无边框窗口、自定义标题栏、朋友圈等核心交互,并附源码解析与打包指南。

你是否想过,用前端技术也能打造出一款媲美原生体验的 PC 微信客户端?本项目正是这样一次尝试:它采用 无边框窗口自定义标题栏 ,让界面更贴近微信原生的沉浸感;好友通讯录、聊天窗口、发送消息、设置管理乃至 朋友圈 等交互一应俱全,几乎复刻了 PC 微信的核心体验。

阅读本文,你将获得:快速上手 的完整步骤、源码解析 的关键实现思路,以及 打包指南,助你从零跑通并二次开发属于自己的桌面应用。

本项目源码下载地址:

源码下载https://download.csdn.net/download/lucky_fang/93461822

项目使用electron+vue3+element-plus+vite+typescript+pinia+router等搭建,各种交互已经写好,参考PC微信客户端样式设计页面元素,包含登录窗口、好友通讯录、聊天记录、聊天窗口、发送消息、设置界面、朋友圈等,使用electron进行应用层实现和通讯,界面使用vue3和前端框架element-plus以及typescript来实现。

项目同时采用组件来布局整个框架,左侧+顶部+导航栏+具体页面功能展示容器。

electron官方文档:app | Electron

element-plus官方文档:Overview 组件总览 | Element Plus

二、项目结构

1.vscode项目截图:

2.项目依赖

三、项目截图

1.登录页

输入账密(admin/123456)登录,登录成功,跳转首页。

2.聊天主页

支持文本、图片样式

3.好友通讯录

好友列表+详情窗口

4.设置管理

账号与安全+通用+存储管理+关于

5.朋友圈

发表朋友圈

发表成功

四、源码解析

1.环境准备

确保你的电脑已安装 ‌Node.js ‌ (建议 v18 LTS 或 v20 LTS) 和 ‌npm ‌。

在 CMD 中输入以下命令检查版本:

node -v npm -v

2.使用脚手架创建项目

这是最标准、坑最少的方式。它将自动初始化 Electron、Vite、Vue3 和 TypeScript 的基础结构。

  1. 执行创建命令‌:

    npm create electron-vite@latest my-electron-app

    注:my-electron-app 是你的项目名称,可以修改。

  2. 按照提示选择配置‌(在 CMD 中通过上下键选择,回车确认):

    • Select a framework ‌: 选择 vue
    • Select a variant ‌: 选择 typescript
    • Package name‌: 直接回车(默认项目名称)
    • Project description‌: 直接回车(可选)
  3. 进入项目目录并安装依赖‌:

    cd my-electron-app npm install

  4. 启动开发服务器‌:

    npm run dev

    此时,你应该能看到一个基本的 Electron 窗口,里面运行着 Vue3 页面。

当然了,如果您下载了本项目源码,就不需要执行以上过程来构建项目了,只需要关心以下命令即可:

1.安装依赖 npm install

2.启动项目 npm run dev 或 npm start

3.win打包 npm run build:win

4.mac打包 npm run build:mac

3.主配置文件源码

electron主文件,index.ts

javascript 复制代码
import { app, shell, BrowserWindow, ipcMain, Menu} from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
let mainWindow: BrowserWindow | null = null
function createWindow(): void {
  // Create the browser window.
   mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    show: false,
    frame: false,
    autoHideMenuBar: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

  if (process.env.NODE_ENV === 'development') {
    mainWindow.webContents.openDevTools()
    
    // 可选:指定打开位置 'right' (默认), 'bottom', 'detach' (独立窗口)
    // mainWindow.webContents.openDevTools({ mode: 'detach' })
  }

  mainWindow.on('ready-to-show', () => {
    if (mainWindow) mainWindow.show()
  })

  mainWindow.on('closed', () => {
    mainWindow = null
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // IPC test
  ipcMain.on('ping', () => console.log('pong'))

  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
// IPC 处理:最小化
ipcMain.on('window-minimize', () => {
  if (mainWindow) mainWindow.minimize()
})

// IPC 处理:关闭(隐藏到托盘或退出,这里简化为退出)
ipcMain.on('window-close', () => {
  if (mainWindow) mainWindow.close()
})

// IPC 处理:打开外部链接
ipcMain.handle('open-external', async (_, url: string) => {
  await shell.openExternal(url)
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
3.1 代码逐段解析

下面按功能模块对主配置文件 index.ts 中的关键代码进行逐段拆解,帮助理解窗口创建、IPC 通信与生命周期管理的实现思路。

3.1.1 模块导入与全局变量
javascript 复制代码
import { app, shell, BrowserWindow, ipcMain, Menu} from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
let mainWindow: BrowserWindow | null = null

这段代码从 electron 模块中导入应用生命周期管理(app)、系统外壳(shell)、窗口创建(BrowserWindow)、进程间通信(ipcMain)以及菜单(Menu)等核心 API。join 来自 path 模块,用于拼接跨平台的路径;electronApp、optimizer、is 来自 @electron-toolkit/utils,提供应用 ID 设置、快捷键优化和环境判断等工具方法。icon 通过 ?asset 后缀引入资源图片,用于 Linux 平台下的窗口图标。mainWindow 声明为可空的全局变量,用于在整个主进程中持有主窗口引用,方便后续对窗口进行最小化、关闭等操作。

3.1.2 创建主窗口
javascript 复制代码
function createWindow(): void {
  mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    show: false,
    frame: false,
    autoHideMenuBar: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

createWindow 函数负责创建应用的主窗口。width 和 height 指定窗口尺寸为 900×670,与仿 PC 微信客户端的界面比例保持一致。show 设为 false 表示窗口先不显示,等待页面渲染完成后再展示,避免白屏闪烁。frame 设为 false 去掉系统默认边框,配合自定义标题栏实现无边框窗口效果,这也是仿微信界面常见的做法。autoHideMenuBar 自动隐藏默认菜单栏。在 Linux 平台下通过展开运算符附加 icon 配置。webPreferences 中 preload 指向预加载脚本,用于在渲染进程与主进程之间建立安全的桥接通道;sandbox 设为 false 允许预加载脚本使用完整的 Node.js 能力。

3.1.3 开发模式与窗口事件
javascript 复制代码
  if (process.env.NODE_ENV === 'development') {
    mainWindow.webContents.openDevTools()
  }

  mainWindow.on('ready-to-show', () => {
    if (mainWindow) mainWindow.show()
  })

  mainWindow.on('closed', () => {
    mainWindow = null
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

开发环境下自动打开开发者工具,方便调试页面。ready-to-show 事件在页面首次渲染完成后触发,此时调用 show 显示窗口,确保用户看到的是完整页面而非加载过程。closed 事件在窗口关闭时将 mainWindow 置为 null,避免引用已销毁的窗口对象。setWindowOpenHandler 拦截渲染进程中所有新窗口打开请求,统一交给系统默认浏览器通过 shell.openExternal 处理,并返回 deny 阻止在应用内创建新窗口,这是 Electron 应用的安全最佳实践。

3.1.4 加载页面资源
javascript 复制代码
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}

这里根据运行环境选择加载方式:开发模式下从 electron-vite 启动的本地开发服务器地址加载页面,支持热更新(HMR),修改渲染进程代码后页面自动刷新;生产模式下则加载打包后的本地 HTML 文件。这种双分支策略是 electron-vite 脚手架的标准写法,兼顾开发体验与发布效率。

3.1.5 应用就绪与生命周期管理
javascript 复制代码
app.whenReady().then(() => {
  electronApp.setAppUserModelId('com.electron')

  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  ipcMain.on('ping', () => console.log('pong'))

  createWindow()

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})|DSML|
app.whenReady() 是 Electron 应用启动的入口,只有在该 Promise 完成后才能创建窗口或使用部分系统 API。setAppUserModelId 为 Windows 平台设置应用用户模型 ID,用于任务栏分组和通知展示。browser-window-created 事件配合 optimizer.watchWindowShortcuts 实现开发环境 F12 开关开发者工具、生产环境屏蔽刷新快捷键等优化。ipcMain.on('ping') 是一个简单的 IPC 测试通道,用于验证主进程与渲染进程的通信是否正常。activate 事件是 macOS 特有的处理逻辑:当点击 Dock 图标且没有其他窗口打开时,重新创建主窗口,符合 macOS 应用的使用习惯。
3.1.6 窗口全部关闭与退出策略
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})|DSML|
window-all-closed 事件在所有窗口关闭后触发。这里做了平台差异化处理:在 macOS 上应用通常保持运行,等待用户通过 Cmd + Q 显式退出;在其他平台(Windows、Linux)上则直接调用 app.quit() 结束进程,释放系统资源。这是 Electron 官方推荐的生命周期管理方式。
3.1.7 IPC 通信:窗口控制与外部链接
ipcMain.on('window-minimize', () => {
  if (mainWindow) mainWindow.minimize()
})

ipcMain.on('window-close', () => {
  if (mainWindow) mainWindow.close()
})

ipcMain.handle('open-external', async (_, url: string) => {
  await shell.openExternal(url)
})|DSML|
这三段代码定义了主进程对外提供的 IPC 接口。window-minimize 和 window-close 分别监听渲染进程发来的最小化、关闭请求,通过 mainWindow 引用调用对应方法,实现无边框窗口的自定义标题栏按钮功能。open-external 使用 ipcMain.handle 注册异步处理函数,接收渲染进程传来的 URL 并调用 shell.openExternal 在系统浏览器中打开,用于处理「查看源码」「访问官网」等外部跳转需求。整体设计思路是:渲染进程不直接操作窗口或系统能力,而是通过 IPC 向主进程发送请求,由主进程统一执行,既保证了功能完整,又遵循了 Electron 的安全隔离原则。

4.项目依赖

package.json

javascript 复制代码
{
  "name": "my-electron-app",
  "version": "1.0.0",
  "description": "An Electron application with Vue and TypeScript",
  "main": "./out/main/index.js",
  "author": "example.com",
  "homepage": "https://electron-vite.org",
  "scripts": {
    "format": "prettier --write .",
    "lint": "eslint --cache .",
    "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
    "typecheck:web": "vue-tsc --noEmit -p tsconfig.web.json --composite false",
    "typecheck": "npm run typecheck:node && npm run typecheck:web",
    "start": "electron-vite preview",
    "dev": "electron-vite dev",
    "build": "npm run typecheck && electron-vite build",
    "postinstall": "electron-builder install-app-deps",
    "build:unpack": "npm run build && electron-builder --dir",
    "build:win": "npm run build && electron-builder --win",
    "build:mac": "npm run build && electron-builder --mac",
    "build:linux": "npm run build && electron-builder --linux"
  },
  "dependencies": {
    "@electron-toolkit/preload": "^3.0.2",
    "@electron-toolkit/utils": "^4.0.0",
    "@element-plus/icons-vue": "^2.3.2",
    "dayjs": "^1.11.10",
    "element-plus": "^2.6.1",
    "pinia": "^2.1.7",
    "vue": "^3.4.21",
    "vue-router": "^4.3.0",
    "pinyin-pro": "^3.18.0"
  },
  "devDependencies": {
    "@electron-toolkit/eslint-config-prettier": "3.0.0",
    "@electron-toolkit/eslint-config-ts": "^3.1.0",
    "@electron-toolkit/tsconfig": "^2.0.0",
    "@types/node": "^22.19.1",
    "@vitejs/plugin-vue": "^6.0.2",
    "electron": "^39.2.6",
    "electron-builder": "^26.0.12",
    "electron-vite": "^5.0.0",
    "eslint": "^9.39.1",
    "eslint-plugin-vue": "^10.6.2",
    "prettier": "^3.7.4",
    "typescript": "^5.9.3",
    "vite": "^7.2.6",
    "vite-plugin-electron": "^0.28.4",
    "vite-plugin-electron-renderer": "^0.14.5",
    "vue": "^3.5.25",
    "vue-eslint-parser": "^10.2.0",
    "vue-tsc": "^3.1.6"
  }
}

五、总结

项目页面完整,后续可能将不断升级,完善其他页面。

关注作者,及时了解更多好项目!

更多优质项目请看作者主页!

获取源码或如需帮助,可通过博客后面名片+作者即可!

源码下载https://download.csdn.net/download/lucky_fang/93461822

其他作品集合

  1. 《vue+element实现电商商城礼品代发网,商品、订单管理》
  2. 《vue+vant2完美实现香奈儿移动端商城网站》
  3. 《vue+elementui实现联想购物商城,样式美观大方》
  4. 《vue+elementui实现英雄联盟道具城》
  5. 《vue+elementui实现app布局小米商城,样式美观大方,功能完整》
  6. 《vue完美模拟pc版快手,实现短视频,含短视频详情播放》
  7. 《vue+element实现蔬菜、水果、电商商城》
  8. 《vue实现美观大方的动漫、cos、帖子类型网站》
  9. 《vue实现好看的相册、图片网站》
  10. 《高度仿PC版《微信读书》,好看的小说、读书网站》
  11. 《vue+element实现非常好看的鲜花网站商城,页面完整,样式美观》
  12. 《vue+elementui+springboot前后端分离实现通用商城管理后台》
  13. 《微信小程序日记、微信小程序个人空间、个人日记》
  14. 《vue+element模仿腾讯视频电影网站》
  15. 《vue+element高度仿照QQ音乐,完美实现PC端QQ音乐》
  16. 《vue+element详细完整实现个人博客、个人网站》
  17. 《vue+elementui+springboot前后端分离实现学校帖子网站,学校大作业》
  18. 《vue+elementui实现U袋网-完整版》
  19. 《vue+element+electron仿微信实现》
  20. 《vue+element模仿电商商城,前后端分离实现,下单微信扫码支付》
  21. 《electron+vue+elementui实现类似QQ窗口靠边自动边缘隐藏》
  22. 《微信小程序仿唯聚时代,微信小程序商城》
  23. 《jquery+bootstrap完整丰富样式开发框架源码,各种现成样式简单易用》
  24. 《html+css响应式旅游主题网站模板,旅游网站,企业文化新闻类网站》
  25. 《css+html各种动态、动画、3D相册等7件套》
  26. 《仿华为电商商城,官网,华为超级新品日demo,大屏霸气且简洁》
  27. 《vue+element简单实现商城网站首页,模仿电商商城》
  28. 《vue+elementui实现非常好看的博客、网站首页,网站模板》
  29. 《elementui+vue实现经典管理系统布局框架,拿来即用》
  30. 《简系统登录页模板html+vue+elementui》
  31. 《vue+elementui完美实现博客、网站、个人网站,高仿"张凯博客"》
  32. 《vue+elementui完美实现后台管理系统的左、右、顶部菜单布局》
  33. 《html5+css3实现3D正方体动画相册2种+3D旋转木马立体动画相册+表白文字加动画爱心+炫酷万花筒五件套含音乐》
  34. 《后端使用springboot+maven+shiro+mybatis+mysql,前端使用H-ui.admin_v3.1.3.1,快速实现管理后台功能》
  35. 《springboot+thymeleaf+maven+html+css实现精美大方好看官网模板完整源码》
  36. 《html+css实现好友列表,类似QQ群聊成员列表》
相关推荐
阿虎儿1 小时前
论 JavaScript 的怪异之处
javascript
你别说话了1 小时前
Vue实现高效拖拽效果 vue-Draggable
前端·vue.js
万物智能2 小时前
PWM散热风扇设置—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
前端·后端·算法
前端柱子2 小时前
q-floodfill白边锯齿?一招搞定抗锯齿边缘问题
前端
梦想的颜色2 小时前
【AI科普】AI 时代,纯 H5+CSS PK React & Vue:前端技术孰优孰劣深入剖析
ai·前端框架·大模型·vue·react·html5·vibecoding
阿虎儿2 小时前
我的 HTML 样板(HTML Boilerplate)
前端·html
Amos_Web2 小时前
Rspack 源码解析(八):Module、Chunk 与 Runtime ID
前端·rust·源码阅读
彭于晏分晏2 小时前
深入理解 Vue 3 响应式原理:从 Proxy 到依赖收集
前端
晚安日记wanna2 小时前
Vue3 script setup 的四层追问答到第三层才算过关
前端·vue.js·面试