# tauri仿微信桌面端NaiveUI版 **Repository Path**: ruirui-study/tauri-wechat-naive-ui-app ## Basic Information - **Project Name**: tauri仿微信桌面端NaiveUI版 - **Description**: tauri仿写微信桌面端,windows版本 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2025-09-30 - **Last Updated**: 2025-10-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: Vue, tauri ## README ## 前言 `Tauri`写桌面端应用太香了,我用`Tauri`仿写了微信,因为很多API都可以用`JavaScript`来写,所以我的整个项目95%都是用`JavaScript`来写各种API的,对前端同学非常友好。 - 项目地址:[https://gitee.com/ruirui-study/tauri-wechat-naive-ui-app:](https://gitee.com/ruirui-study/tauri-wechat-naive-ui-app) - 掘金文章:[https://juejin.cn/post/7564540677469028393](https://juejin.cn/post/7564540677469028393) - CSDN文章:[https://blog.csdn.net/yan1915766026/article/details/153815319](https://blog.csdn.net/yan1915766026/article/details/153815319) - 今日头条:[https://www.toutiao.com/article/7564661091976938025/](https://www.toutiao.com/article/7564661091976938025/) ![img.png](screen/img.gif) ``` 项目的screen文件夹,专门用来放readme.md截图资源的,没啥用 ``` #### 分支说明 - master: 主分支,默认分支 - dev: 开发分支,通常比master分支多一些,因为dev分支是开发分支,新功能测试都在该分支下,完成后才合并主分支 #### 启动说明 前提是你本地安装好了rust环境,node环境等,本人用的是nodejs22版本,官方说明最低18版本,具体可我没试过。 然后运行 `pnpm install` 安装依赖 然后运行 `pnpm run tauri dev` 启动项目,这个过程可能稍慢,因为它同时安装rust的构建工具,所以要花点时间。 启动成功后,你就可以用你熟悉的vue来开发了,直接添加路由即可…… ## 技术栈 * vue3全家桶(vue-router、pinia) * `Naive UI`:写界面的UI库 * rust:写底层交互,占比极少 * `JavaScript`:写`Tauri`的API,占比大 * 其他工具类库…… ![img_5.png](screen/img_5.png) ## 资源占用 不得不说,`Tauri`的资源占用真的好,我引入了好几百kb的图片文件,`Naive UI`全部引入,还有很多svg图片,就是这样的情况下,打包后的安装包也才2.57M,我当时就惊了! * 安装包:2.57M * 直接运行包:10.1M * 内存占用:60M(2个窗口) ![img_2.png](screen/img_2.png) ## 细节怪 写桌面端的都是细节怪,如果是单一窗口也还好,可以像写网页一样一直写下去…… 但是桌面端还要考虑多窗口,托盘图标、托盘菜单、窗口通信、底层权限、原生通知、进程管理等,随便拿出一个来都够研究半天的了。 我为了高度还原桌面微信,也是把细节拉满了 * 创建窗口,如果窗口已存在、则聚焦窗口使其显示,而不是打印错误提示、这样看不到效果的,也不能提示“窗口已存在,请勿重复创建吧”,这样体验感直线下降!创建窗口分3种情况: 1. 窗口已存在,且为最小化状态的,则取消窗口最小化; 2. 窗口已存在,且为显示状态,但是在其他应用的窗口下面,则聚焦显示到前台; 3. 窗口不存在,才执行创建窗口的方法 * 自定义托盘菜单、及菜单窗口(默认隐藏) * 窗口失去焦点时,则隐藏托盘菜单窗口 * 鼠标右击、精确计算显示位置 * 鼠标左击,显示主聊天窗口 * 自定义按钮功能,可放任意内容,脱离原生托盘菜单的限制 * 高度前端化,很多API都是用JavaScript编写,只有少数用rust编写,且注释清晰; * 自定义最大化、最小化、关闭、置顶菜单栏,且组件化; * 自定义可拖拽标题栏,组件化; * 多处调用原生API,带有演示作用; ![img_3.png](screen/img_3.png) ## 已完成模块 * [x] 基础架构布局 * 聊天(含右键菜单,发送消息窗口、split栏未优化,截图功能、聊天记录等按钮功能未模拟) * 通讯录(只模拟了UI界面、逻辑跳转等) * 收藏(只模拟了UI界面) * 设置(退出登录、选择存储位置等功能已模拟) * 其他窗口:朋友圈、搜一搜、小程序、表情窗口等 * [x] 登录、退出登录功能已模拟,主要包含跨窗口通信问题 * [x] 自定义托盘菜单 * [x] 自定义最大化、最小化、置顶菜单栏 * [x] 自定义可拖拽标题栏 * [x] 原生消息通知演示功能 * [x] 使用默认浏览器打开链接 * [x] 退出程序 * [x] 自定义应用图标配置 * [x] 白屏优化 ![img_4.png](screen/img_4.png) ## 待优化/待开发 * [ ] 聊天界面:输入框样式优化,拖动窗格分割面板 * [ ] 表情包窗口:显示位置优化 * [ ] 其他有些内容,没给点击提示 * [ ] 滚动条可以再美化一些 * [ ] 其他还有很多空白窗口,暂时只放了空的内容 * [ ] 聊天列表,拖动独立聊天窗口 * [ ] 本地数据持久化,配置项持久化等 * [ ] 开机自启动 * [ ] 截图功能 * [ ] 便利贴功能 * [ ] naive ui改为按需引入,目前为了开发方便,暂时全局引入的 * [ ] 启动画面 ![img_6.png](screen/img_6.png) ## 小小心得 其实,大部分的API都可以用纯前端`JavaScript`的方式来完成,但是有些内容还是要用rust写的,尤其是需要用到跨窗口状态的。 #### 登录 比如登录窗口,登陆成功后一般是在`pinia`中设置一个变量`isLogin`默认值为false,然后把`isLogin`改为true,然后其他地方引用`isLogin`,但是如果是跨窗口的话,你只有在登录窗口的`isLogin`值为true,其他窗口的`isLogin`值还是默认的false。 同样地,你也不能用`localStorage`等方法,虽然这会在跨窗口中获取同样的缓存值,但是当应用退出程序后,再次打开应用时的`isLogin`还是缓存的true值,但是默认打开的是登录页,你可能会说,我在退出应用的时候清空缓存值不就好了吗,但是有时候用户不是通过退出按钮来退出的,有的直接关电脑或断电了呢,那么你该怎么监听? 所以说,还是得用到rust,直接在rust全局中记录登录的状态值,前端页面直接invoke这个变量即可,不管你是哪个窗口获取的值都一样,下次重启应用时,rust中初始化的`isLogin`值又变为false了,这就很符合我们的预期了。 #### 托盘 未登录不显示托盘,已登录才显示托盘。 这是一个很常见的需求,如果你没有跨窗口的说法,那么用纯JavaScript写也是OK的,但是如果你有跨窗口的情况,那么就需要用到`rust`了,因为托盘用到的是一个实例,你在主窗口`main`显示时创建托盘,托盘实例为`trayInstance`,你在退出登录后,销毁主窗口`main`,创建登录窗口`login`,但是只要你销毁主窗口`main`,那么托盘实例`trayInstance`也就没有,也就无法销毁了。 可能你会说,我在销毁主窗口main之前的`trayInstance`实例还在的,我先销毁`trayInstance`实例不就行了吗?你可以试试看…… ![img_7.png](screen/img_7.png)