Tauri-Vue3桌面端聊天室|tauri+vite3仿微信|tauri聊天程序EXE
基于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的更多相关文章
- electron聊天室|vue+electron-vue仿微信客户端|electron桌面聊天
一.项目概况 基于Electron+vue+electron-vue+vuex+Nodejs+vueVideoPlayer+electron-builder等技术仿制微信电脑端界面聊天室实例,实现消息 ...
- vue聊天室|h5+vue仿微信聊天界面|vue仿微信
一.项目简介 基于Vue2.0+Vuex+vue-router+webpack2.0+es6+vuePhotoPreview+wcPop等技术架构开发的仿微信界面聊天室——vueChatRoom,实现 ...
- react聊天室|react+redux仿微信聊天IM实例|react仿微信界面
一.项目概况 基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+react-photoswipe+swiper等技术混合开 ...
- Svelte3聊天室|svelte+svelteKit仿微信聊天实例|svelte.js开发App
基于svelte3.x+svelteKit构建仿微信App聊天应用svelte-chatroom. svelte-chatroom 基于svelte.js+svelteKit+mescroll.js+ ...
- Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例
一.项目简述 taro-chatroom是基于Taro多端实例聊天项目,运用Taro+react+react-redux+taroPop+react-native等技术开发的仿微信App界面聊天室,实 ...
- uni-app聊天室|vue+uniapp仿微信聊天实例|uniapp仿微信App界面
一.介绍 运用UniApp+Vue+Vuex+swiper+uniPop等技术开发的仿微信原生App聊天室|仿微信聊天界面实例项目uniapp-chatroom,实现了发送图文消息.表情(gif图), ...
- html5聊天案例|趣聊h5|仿微信界面聊天|红包|语音聊天|地图
之前有开发过一个h5微直播项目,当时里面也用到过聊天模块部分,今天就在之前聊天部分的基础上重新抽离模块,开发了这个h5趣聊项目,功能效果比较类似微信聊天界面.采用html5+css3+Zepto+sw ...
- h5移动端聊天室|仿微信界面聊天室|h5多人聊天室
今年的FIFA世界杯甚是精彩,最近兴致高涨就利用HTML5开发了一个手机端仿微信界面聊天室,该h5聊天室采用750px全新伸缩flex布局,以及使用rem响应式配合fontsize.js,页面弹窗则是 ...
- uniapp+nvue实现仿微信App聊天应用 —— 成功实现好友聊天+语音视频通话功能
基于uniapp + nvue实现的uniapp仿微信App聊天应用 txim 实例项目,实现了以下功能. 1: 聊天会话管理 2: 好友列表 3: 文字.语音.视频.表情.位置等聊天消息收发 4: ...
随机推荐
- LuoguP2876 [USACO07JAN]解决问题Problem Solving (区间DP)(未完成)
#include "Head.cpp" const int N = 307; int f[N][N], a[N], b[N], sumA[N], sumB[N]; int main ...
- 数据库运维之路——关于tempdb暴增实战案例
转眼间,2021年的第一个季度已经到了最后一个月了,由于疫情原因,最近一段时间一直在北京,基本上没有出差,每天上班下班的日子感觉时间过的好快,新的一年继续努力奋斗啊. 仔细回想一下,自己踏入到sql ...
- Mysql 实现数据库读写分离
Amoeba+Mysql实现数据库读写分离 一.Amoeba 是什么 Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发.座落与Client.DB Server(s)之间.对客户端透明. ...
- 基于Anacoda搭建虚拟环境cudnn6.0+cuda8.0+python3.6+tensorflow-gpu1.4.0
!一定要查准cudnn,cuda,tensorflow-gpu对应的版本号再进行安装,且本文一切安装均在虚拟环境中完成. 下文以笔者自己电脑为例,展开安装教程阐述(省略anaconda安装教程): 1 ...
- 造序列(构造,DP)
题面 Sample Input 7 8 7 10 31 20 100 869120 Sample Output 6 1 1 4 5 1 4 7 1 9 1 9 8 1 0 8 1 9 4 9 1 0 ...
- java数组---概念
1.数组的定义 数组是相同类型数据的有序集合.数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成.其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 2.数组的建 ...
- Clickhouse基准测试实践
1.概述 本篇博客将对MySQL.InfluxDB.Clickhouse在写入时间.聚合查询时间.磁盘使用等方面的性能指标来进行比较. 2.内容 比较的数据集,是使用的Clickhouse官网提供的6 ...
- java代码审计的点
java代码审计的点 组件的审计 首先看pom.xml查看第三方组件和第三方组件的版本 常用的第三方组件: 第三方组件 漏洞类型 组件漏洞版本 log4j2 远程代码执行 Apache log4j2 ...
- RTSP鉴权认证之基础认证和摘要认证区别
RTSP认证类型 基本认证(basic authentication):http 1.0提出的认证方案,其消息传输不经过加密转换因此存在严重的安全隐患.: 摘要认证(digest authentica ...
- KingbaseES V8R6单实例外部备份故障案例
案例说明: 在KingbaseES V8R6单实例环境,配置外部备份服务器使用sys_backup.sh物理备份时,出现以下"WAL segment xxx was not archived ...