当前位置:   article > 正文

vue3-tauri-chat:基于tauri聊天实例|tauri仿微信客户端

ue3-tauri-chat

Vue3.js+Tauri桌面端聊天实例|tauri仿微信/QQ聊天TauriChat。

基于tauri+vite3.x+vue3+element-plus等技术开发客户端仿微信/QQ聊天实战案例。实现发送消息、预览图片/视频/网址链接、拖拽/粘贴发送图片、朋友圈等功能。

 

使用技术

  • 编辑器: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新开多窗体 

tauri官网提供了几种创建新窗口的方法,这里封装了一种前端方法。

  1. // 关于
  2. const openAboutWin = () => {
  3. createWin({
  4. label: 'about',
  5. title: '关于',
  6. url: '/about',
  7. width: 430,
  8. height: 330,
  9. resizable: false,
  10. alwaysOnTop: true,
  11. })
  12. }
  13. // 主题换肤
  14. const openThemeSkinWin = () => {
  15. createWin({
  16. label: 'skin',
  17. title: '换肤',
  18. url: '/skin',
  19. width: 630,
  20. height: 400,
  21. resizable: false,
  22. })
  23. }
  24. // 朋友圈
  25. const openQzoneWin = () => {
  26. createWin({
  27. label: 'fzone',
  28. title: '朋友圈',
  29. url: '/fzone',
  30. width: 550,
  31. height: 700,
  32. resizable: false,
  33. })
  34. }

vue3+tauri 创建多开窗口桌面应用_xiaoyan_2018的博客-CSDN博客_tauri 例子

tauri自定义拖拽窗体

配置decorations: false,创建的窗口会无边框及导航操作。

tauri设置 data-tauri-drag-region 属性,该区域就能自由拖拽了。

  1. <template>
  2. <div class="nt__navbar">
  3. <div data-tauri-drag-region class="nt__navbar-wrap">
  4. <div class="nt__navbar-title">
  5. <template v-if="$slots.title"><slot name="title" /></template>
  6. <template v-else>{{title}}</template>
  7. </div>
  8. </div>
  9. <WinTool :minimizable="minimizable" :maximizable="maximizable" :closable="closable">
  10. <slot name="wbtn" />
  11. </WinTool>
  12. </div>
  13. </template>

tauri+vite3创建登录窗口|tauri自定义拖拽区域_xiaoyan_2018的博客-CSDN博客

tauri创建系统托盘

  1. /**
  2. * 创建系统托盘图标Tray
  3. */
  4. use tauri::{
  5. AppHandle, Manager,
  6. CustomMenuItem, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, SystemTraySubmenu
  7. };
  8. // 托盘菜单
  9. pub fn menu() -> SystemTray {
  10. let exit = CustomMenuItem::new("exit".to_string(), "退出");
  11. let relaunch = CustomMenuItem::new("relaunch".to_string(), "重启应用");
  12. let show = CustomMenuItem::new("show".to_string(), "显示窗口");
  13. let hide = CustomMenuItem::new("hide".to_string(), "隐藏窗口");
  14. let change_ico = CustomMenuItem::new("change_ico".to_string(), "更换托盘图标");
  15. let tray_menu = SystemTrayMenu::new()
  16. .add_submenu(SystemTraySubmenu::new(
  17. "国际化", // 语言菜单
  18. SystemTrayMenu::new()
  19. .add_item(CustomMenuItem::new("lang_english".to_string(), "English"))
  20. .add_item(CustomMenuItem::new("lang_zh_CN".to_string(), "简体中文"))
  21. .add_item(CustomMenuItem::new("lang_zh_HK".to_string(), "繁体中文")),
  22. ))
  23. .add_native_item(SystemTrayMenuItem::Separator) // 分割线
  24. .add_item(change_ico)
  25. .add_native_item(SystemTrayMenuItem::Separator)
  26. .add_item(hide)
  27. .add_item(show)
  28. .add_native_item(SystemTrayMenuItem::Separator)
  29. .add_item(relaunch)
  30. .add_item(exit);
  31. SystemTray::new().with_menu(tray_menu)
  32. }
  33. // 托盘事件
  34. pub fn handler(app: &AppHandle, event: SystemTrayEvent) {
  35. match event {
  36. SystemTrayEvent::LeftClick {
  37. position: _,
  38. size: _,
  39. ..
  40. } => {
  41. println!("点击左键");
  42. }
  43. SystemTrayEvent::RightClick {
  44. position: _,
  45. size: _,
  46. ..
  47. } => {
  48. println!("点击右键");
  49. }
  50. SystemTrayEvent::DoubleClick {
  51. position: _,
  52. size: _,
  53. ..
  54. } => {
  55. println!("双击");
  56. app.emit_all("win-show", {}).unwrap();
  57. }
  58. SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
  59. // 更新托盘图标
  60. "change_ico" => {
  61. app.tray_handle()
  62. .set_icon(tauri::Icon::Raw(
  63. include_bytes!("../icons/tray-empty.ico").to_vec()
  64. ))
  65. .unwrap();
  66. }
  67. // 选择语言,匹配 id 前缀包含 `lang_` 的事件
  68. lang if lang.contains("lang_") => {
  69. Lang::new(
  70. app,
  71. id,
  72. vec![
  73. Lang {
  74. name: "English",
  75. id: "lang_english",
  76. },
  77. Lang {
  78. name: "繁体中文",
  79. id: "lang_zh_HK",
  80. },
  81. Lang {
  82. name: "简体中文",
  83. id: "lang_zh_CN",
  84. },
  85. ],
  86. );
  87. }
  88. "hide" => {
  89. // println!("点击隐藏");
  90. app.emit_all("win-hide", {}).unwrap();
  91. }
  92. "show" => {
  93. // println!("点击显示");
  94. app.emit_all("win-show", {}).unwrap();
  95. }
  96. "relaunch" => {
  97. // println!("点击重启");
  98. app.emit_all("win-relaunch", {}).unwrap();
  99. }
  100. "exit" => {
  101. // println!("点击退出");
  102. app.emit_all("win-exit", {}).unwrap();
  103. }
  104. _ => {}
  105. },
  106. _ => {}
  107. }
  108. }
  109. struct Lang<'a> {
  110. name: &'a str,
  111. id: &'a str,
  112. }
  113. impl Lang<'static> {
  114. fn new(app: &AppHandle, id: String, langs: Vec<Lang>) {
  115. // 获取点击的菜单项的句柄
  116. langs.iter().for_each(|lang| {
  117. let handle = app.tray_handle().get_item(lang.id);
  118. if lang.id.to_string() == id.as_str() {
  119. // 设置菜单名称
  120. handle.set_title(format!(" {}", lang.name)).unwrap();
  121. handle.set_selected(true).unwrap();
  122. } else {
  123. handle.set_title(lang.name).unwrap();
  124. handle.set_selected(false).unwrap();
  125. }
  126. });
  127. }
  128. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/753624
推荐阅读
相关标签