乐趣区

关于vue3:vue3tauri聊天室taurirust跨端实例tauri仿微信

上一篇有给大家分享 Tauri 创立多窗口利用实际。明天分享最新开发的 Tauri+Vite3 客户端聊天实例我的项目。

tauri-vue3-chat 基于 tauri+vue3+vite3+element-plus+v3layer 等技术开发仿微信客户端利用。

实现了发送图文音讯、图片 + 视频 + 网址预览、拖拽发送图片、朋友圈等性能。反对 tauri 关上多个窗体、主题换肤等性能。

技术框架

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

tauri 多开窗体

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,
    })
}

反对如下参数配置

// 窗口配置
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 参数,则创立的窗口没有顶部导航栏及边框。须要自定义拖拽性能。

设置 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 创立零碎拖拽

/**
 * 创立系统托盘图标 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+vue3 创立聊天实例就先分享这么多吧。

https://segmentfault.com/a/11…

https://segmentfault.com/a/11…

退出移动版