基于Tauri+Vue3+Rust+ElementPlus桌面端聊天实例

TauriChat 基于 tauri+rust+vue3+element-plus 等技术开发桌面端仿微信 EXE 软件。

技术框架#

  • 编辑器: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 创建多窗口#

Tauri 集成 Vue3 技术开发桌面端应用实践,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 创建多开窗体,可以去看看。
tauri+vite3 创建多窗口应用

支持如下窗口参数配置

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,         // 隐藏窗口
}

tauri 自定义拖拽区域#

如下图:项目中的窗口顶部采用无边框模式 decorations: false
基于Tauri+Vue3+Rust+ElementPlus桌面端聊天实例

设置 data-tauri-drag-region 属性,就可以拖动窗口了。

基于Tauri+Vue3+Rust+ElementPlus桌面端聊天实例

<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 自定义最小化 / 最大化 / 关闭按钮功能

tauri 自定义托盘图标#

基于Tauri+Vue3+Rust+ElementPlus桌面端聊天实例

在 tauri.conf.json 中配置

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

基于Tauri+Vue3+Rust+ElementPlus桌面端聊天实例

/**
 * 创建系统托盘图标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();
            }
        });
    }
}

如果提示 ico 图标报错,需要在 Cargo.toml 中配置 png/ico。

基于Tauri+Vue3+Rust+ElementPlus桌面端聊天实例

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 桌面聊天 EXE 应用的一些分享。
Electron-MacUI 桌面管理应用 | electron13+vue3.x 仿 mac 桌面 OS

本作品采用《CC 协议》,转载必须注明作者和本文链接
本文为原创文章,未经作者允许不得转载,欢迎大家一起交流 QQ(282310962) wx(xy190310)
文章
65
粉丝
52
喜欢
108
收藏
57
排名:356
访问:2.7 万
私信
所有博文
博客标签
展开
社区赞助商