基于tauri+vue3.js+vite3跨桌面端仿微信聊天实例TauriVue3Chat

tauri-chat 运用最新tauri+vue3+vite3+element-plus+v3layer等技术跨桌面端仿微信|QQ聊天程序EXE。基本实现了发送图文混排消息、图片/视频/网址预览、拖拽聊天区发送图片、朋友圈等功能。支持tauri打开多个窗体、更换主题皮肤等功能。

一、技术框架

  • 编辑器:VScode
  • 使用技术:tauri+vue^3.2.37+vite^3.0.2+vuex4+vue-router@4
  • UI组件库:element-plus^2.2.17 (饿了么vue3组件库)
  • 弹窗组件:v3layer(基于vue3自定义pc端弹窗组件)
  • 滚动条组件:v3scroll(基于vue3模拟滚动条组件)
  • 矢量图标:阿里iconfont字体图标库

二、项目结构

◆ Tauri新建多开窗口

项目中主题换肤、朋友圈、关于、视频预览等窗口均是新开窗口。

// 关于
const openAboutWin = () => {
createWin({
label: 'about',
title: '关于',
url: '/about',
width: 430,
height: 330,
resizable: false,
alwaysOnTop: true,
})
} // 主题换肤
const openThemeSkinWin = () => {
createWin({
label: 'skin',
title: '换肤',
url: '/skin',
width: 630,
height: 400,
resizable: false,
})
} // 朋友圈
const openQzoneWin = () => {
createWin({
label: 'fzone',
title: '朋友圈',
url: '/fzone',
width: 550,
height: 700,
resizable: false,
})
}

tauri多窗口参数配置

// 窗口配置
export const windowConfig = {
label: null, // 窗口唯一label
title: '', // 窗口标题
url: '', // 路由地址url
width: 900, // 窗口宽度
height: 640, // 窗口高度
minWidth: null, // 窗口最小宽度
minHeight: null, // 窗口最小高度
x: null, // 窗口相对于屏幕左侧坐标
y: null, // 窗口相对于屏幕顶端坐标
center: true, // 窗口居中显示
resizable: true, // 是否支持缩放
maximized: false, // 最大化窗口
decorations: false, // 窗口是否无边框及导航条
alwaysOnTop: false, // 置顶窗口
fileDropEnabled: false, // 禁止系统拖放
visible: false, // 隐藏窗口
}

由于之前有写过一篇vue3+tauri创建多窗口的分享文章,这里就不详细介绍了。

https://www.cnblogs.com/xiaoyan2017/p/16812092.html

◆ Tauri自定义拖拽窗体|最大化/最小化/关闭功能

创建窗口的时候配置 decorations: false 参数,则创建的窗口没有顶部导航栏及边框。拖拽区域/最大化/最小化及关闭按钮都需要自定义功能。

tauri提供了 data-tauri-drag-region 属性,在需要拖拽的元素上设置该属性,该区域就能自由拖拽了。

<template>
<div class="nt__navbar">
<div data-tauri-drag-region class="nt__navbar-wrap">
<div class="nt__navbar-title">
<template v-if="$slots.title"><slot name="title" /></template>
<template v-else>{{title}}</template>
</div>
</div>
<WinTool :minimizable="minimizable" :maximizable="maximizable" :closable="closable">
<slot name="wbtn" />
</WinTool>
</div>
</template>

下面这篇文章介绍tauri自定义最大化/最小化及关闭按钮功能。

https://www.cnblogs.com/xiaoyan2017/p/16818283.html

◆ Tauri创建系统托盘图标

当关闭窗体的时候,会判断是否主窗口,并给出关闭提示。当不是主窗口,则直接关闭,是主窗口则给出下图弹窗提示。最小化至托盘 则是隐藏窗口,退出程序则直接执行exit方法退出应用了。

// 关闭窗体
const handleCloseWindow = async() => {
if(appWindow.label.indexOf('main') > -1) {
let $el = v3layer({
type: 'android',
content: '确认退出应用程序吗?',
btns: [
{
text: '最小化托盘',
style: 'color:#24c8db',
click: () => {
$el.close()
await appWindow.hide()
}
},
{
text: '退出程序',
style: 'color:#ff5438',
click: async() => {
$el.close()
store.commit('LOGOUT')
await exit()
}
}
]
})
}else {
await appWindow.close()
}
}

/**
* 创建系统托盘图标Tray
*/ use tauri::{
AppHandle, Manager,
CustomMenuItem, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, SystemTraySubmenu
}; // 托盘菜单
pub fn menu() -> SystemTray {
let exit = CustomMenuItem::new("exit".to_string(), "退出");
let relaunch = CustomMenuItem::new("relaunch".to_string(), "重启应用");
let show = CustomMenuItem::new("show".to_string(), "显示窗口");
let hide = CustomMenuItem::new("hide".to_string(), "隐藏窗口");
let change_ico = CustomMenuItem::new("change_ico".to_string(), "更换托盘图标");
let tray_menu = SystemTrayMenu::new()
.add_submenu(SystemTraySubmenu::new(
"国际化", // 语言菜单
SystemTrayMenu::new()
.add_item(CustomMenuItem::new("lang_english".to_string(), "English"))
.add_item(CustomMenuItem::new("lang_zh_CN".to_string(), "简体中文"))
.add_item(CustomMenuItem::new("lang_zh_HK".to_string(), "繁体中文")),
))
.add_native_item(SystemTrayMenuItem::Separator) // 分割线
.add_item(change_ico)
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(hide)
.add_item(show)
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(relaunch)
.add_item(exit); SystemTray::new().with_menu(tray_menu)
} // 托盘事件
pub fn handler(app: &AppHandle, event: SystemTrayEvent) {
match event {
SystemTrayEvent::LeftClick {
position: _,
size: _,
..
} => {
println!("点击左键");
}
SystemTrayEvent::RightClick {
position: _,
size: _,
..
} => {
println!("点击右键");
}
SystemTrayEvent::DoubleClick {
position: _,
size: _,
..
} => {
println!("双击");
app.emit_all("win-show", {}).unwrap();
}
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
// 更新托盘图标
"change_ico" => {
app.tray_handle()
.set_icon(tauri::Icon::Raw(
include_bytes!("../icons/tray-empty.ico").to_vec()
))
.unwrap();
}
// 选择语言,匹配 id 前缀包含 `lang_` 的事件
lang if lang.contains("lang_") => {
Lang::new(
app,
id,
vec![
Lang {
name: "English",
id: "lang_english",
},
Lang {
name: "繁体中文",
id: "lang_zh_HK",
},
Lang {
name: "简体中文",
id: "lang_zh_CN",
},
],
);
}
"hide" => {
// println!("点击隐藏");
app.emit_all("win-hide", {}).unwrap();
}
"show" => {
// println!("点击显示");
app.emit_all("win-show", {}).unwrap();
}
"relaunch" => {
// println!("点击重启");
app.emit_all("win-relaunch", {}).unwrap();
}
"exit" => {
// println!("点击退出");
app.emit_all("win-exit", {}).unwrap();
}
_ => {}
},
_ => {}
}
} struct Lang<'a> {
name: &'a str,
id: &'a str,
} impl Lang<'static> {
fn new(app: &AppHandle, id: String, langs: Vec<Lang>) {
// 获取点击的菜单项的句柄
langs.iter().for_each(|lang| {
let handle = app.tray_handle().get_item(lang.id);
if lang.id.to_string() == id.as_str() {
// 设置菜单名称
handle.set_title(format!(" {}", lang.name)).unwrap();
handle.set_selected(true).unwrap();
} else {
handle.set_title(lang.name).unwrap();
handle.set_selected(false).unwrap();
}
});
}
}

tauri创建托盘图标默认读取 src-tauri/icons 目录下图标,如果自定义的.ico图标,可在tauri.cong.json文件中配置。

"systemTray": {
"iconPath": "icons/tray.ico",
"iconAsTemplate": true,
"menuOnLeftClick": false
}

使用ico图标报错,需要在 src-tauri/src/Cargo.toml 中配置 icon-ico 或 icon-png

tauri build 打包构建,如果打包的时候报错,需要在 src-tauri/tauri.conf.json 这个配置文件中找到 identifier 这个字段,将它的值进行更改即可。

tauri.conf.json配置文件

{
"build": {
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build",
"devPath": "http://localhost:1420",
"distDir": "../dist",
"withGlobalTauri": false
},
"package": {
"productName": "tauri-chat",
"version": "0.0.0"
},
"tauri": {
"allowlist": {
"all": true
},
"bundle": {
"active": true,
"category": "DeveloperTool",
"copyright": "",
"deb": {
"depends": []
},
"externalBin": [],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "com.tauri.chat",
"longDescription": "",
"macOS": {
"entitlements": null,
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"resources": [],
"shortDescription": "",
"targets": "all",
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
},
"security": {
"csp": null
},
"updater": {
"active": false
},
"windows": [
{
"fullscreen": false,
"height": 640,
"resizable": true,
"title": "TAURI-CHAT",
"width": 900,
"center": true,
"decorations": false,
"fileDropEnabled": false,
"visible": false
}
],
"systemTray": {
"iconPath": "icons/tray.ico",
"iconAsTemplate": true,
"menuOnLeftClick": false
}
}
}

Oker,基于tauri+vue3实战桌面端聊天应用就分享到这里,希望对大家有些帮助。

最后附上一个uniapp+uview跨端后台管理系统

https://www.cnblogs.com/xiaoyan2017/p/15836112.html

Tauri-Vue3桌面端聊天室|tauri+vite3仿微信|tauri聊天程序EXE的更多相关文章

  1. electron聊天室|vue+electron-vue仿微信客户端|electron桌面聊天

    一.项目概况 基于Electron+vue+electron-vue+vuex+Nodejs+vueVideoPlayer+electron-builder等技术仿制微信电脑端界面聊天室实例,实现消息 ...

  2. vue聊天室|h5+vue仿微信聊天界面|vue仿微信

    一.项目简介 基于Vue2.0+Vuex+vue-router+webpack2.0+es6+vuePhotoPreview+wcPop等技术架构开发的仿微信界面聊天室——vueChatRoom,实现 ...

  3. react聊天室|react+redux仿微信聊天IM实例|react仿微信界面

    一.项目概况 基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+react-photoswipe+swiper等技术混合开 ...

  4. Svelte3聊天室|svelte+svelteKit仿微信聊天实例|svelte.js开发App

    基于svelte3.x+svelteKit构建仿微信App聊天应用svelte-chatroom. svelte-chatroom 基于svelte.js+svelteKit+mescroll.js+ ...

  5. Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

    一.项目简述 taro-chatroom是基于Taro多端实例聊天项目,运用Taro+react+react-redux+taroPop+react-native等技术开发的仿微信App界面聊天室,实 ...

  6. uni-app聊天室|vue+uniapp仿微信聊天实例|uniapp仿微信App界面

    一.介绍 运用UniApp+Vue+Vuex+swiper+uniPop等技术开发的仿微信原生App聊天室|仿微信聊天界面实例项目uniapp-chatroom,实现了发送图文消息.表情(gif图), ...

  7. html5聊天案例|趣聊h5|仿微信界面聊天|红包|语音聊天|地图

    之前有开发过一个h5微直播项目,当时里面也用到过聊天模块部分,今天就在之前聊天部分的基础上重新抽离模块,开发了这个h5趣聊项目,功能效果比较类似微信聊天界面.采用html5+css3+Zepto+sw ...

  8. h5移动端聊天室|仿微信界面聊天室|h5多人聊天室

    今年的FIFA世界杯甚是精彩,最近兴致高涨就利用HTML5开发了一个手机端仿微信界面聊天室,该h5聊天室采用750px全新伸缩flex布局,以及使用rem响应式配合fontsize.js,页面弹窗则是 ...

  9. uniapp+nvue实现仿微信App聊天应用 —— 成功实现好友聊天+语音视频通话功能

    基于uniapp + nvue实现的uniapp仿微信App聊天应用 txim 实例项目,实现了以下功能. 1: 聊天会话管理 2: 好友列表 3: 文字.语音.视频.表情.位置等聊天消息收发 4: ...

随机推荐

  1. Redis 10 位图

    参考源 https://www.bilibili.com/video/BV1S54y1R7SB?spm_id_from=333.999.0.0 版本 本文章基于 Redis 6.2.6 概述 Redi ...

  2. [游记]CSP 2021 J/S

    这一次,也许是我的OI生涯的转折点了--能过,学习OI的时间就不会减少:但不能过,就会减少学习OI的时间-- 上午(S组) 6:00起床.去吃早餐,结果因为边喝粥边喝牛奶导致肚子疼.(我在这里劝大家, ...

  3. UE蓝图---实现场景物体Transform状态重置效果

    在工业领域应用中,通常会遇到操作场景模型变换的操作,经过了移动.旋转.缩放后,要求可一键重置还原最初的Transform状态. 思路:1.在模型阶段设置每个模型Tag值为Oper,表明是可被操作的对象 ...

  4. 【JavaWeb】学习路径1-背景

    JavaWeb系列也是一个非常庞大的系列,主要分为五个部分讲解: HTML JSP和Servlet CSS的讲解 JavaScrip的讲解 jQuery框架的讲解 学习完上述内容后,就能够基本了解一个 ...

  5. KingbaseES 全局索引是否因为DDL操作而变为Unusable ?

    前言 Oracle 在对分区做DDL操作时,会使分区全局索引失效,需要加上关键字update global indexes.KingbaseES 同样支持全局索引.那么,如果对分区表进行DDL操作,那 ...

  6. 【读书笔记】C#高级编程 第三章 对象和类型

    (一)类和结构 类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法. 类和结构的区别:内存中的存储方式.访问方式(类是存储在堆上的引用类型,结构是存储在栈的值类型)和它 ...

  7. 不建议升级windows11的理由

    此文写于2022年9月13日,用于警告那些蠢蠢欲动想升级win11的伙伴. win11发布后,最亮眼的功能当然是自带"安卓模拟器",但作为一名程序开发者的我其实是不愿意马上尝鲜的, ...

  8. 【一月一本技术书】-【MySQL是怎样运行的】- 8月

    mysql 基础 mysql分为 客戶端/服务端 客户端向服务端发送一段文本(mysql语句),服务器处理后向客户端进程返回一段文本. 查询请求执行过程 客户端->处理连接->查询缓存-& ...

  9. 绕过CDN获取服务器真实IP地址

    相关视频链接:(https://blog.sechelper.com/20220914/penetration-testing-guide/cdn-bypass) CDN(Content Delive ...

  10. .NET Core Web APi类库如何内嵌运行?

    话题 我们知道在.NET Framework中可以嵌入运行Web APi,那么在.NET Core(.NET 6+称之为.NET)中如何内嵌运行Web Api呢,在实际项目中这种场景非常常见,那么我们 ...