Tauri2 vue3 rust js 托盘图标闪烁及未读消息小窗展示
ps: 对于rust语言不熟悉, 国内资料匮乏,所参考不完整,所幸仔细阅读文档后,最终实现了效果
工程初始化
可以参考往期的Tauri的博客文章《Tauri小而美》
托盘图标闪烁
托盘图标闪烁目前方案为周期性设置托盘图标的显示和隐藏,
参考自:
https://v2.tauri.app/plugin/system-tray/
https://www.cnblogs.com/xiaoyan2017/p/18416811
可以看到Tauri官网的Demo为js语言和rust语言,rust语言使用不熟练,所以采用了js+rust的方式来实现
首先在文件目录中创建tray.rs文件, 完成托盘图标的初始化
按此目录结构选取一张托盘展示图片
然后在tauri.conf.json中添加参数供系统识别图片位置
// tray.rs 全文件
use tauri::{
Emitter,
Manager,
Runtime,
};
// 托盘菜单定义设置
pub fn create_tray<R: tauri::Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
// 创建托盘图标
let _tray = tauri::tray::TrayIconBuilder::with_id("tray") // 托盘图标ID
// .menu(&menu)
.tooltip("金投")
.icon(app.default_window_icon().unwrap().clone())
.on_menu_event(move |app, event| match event.id.as_ref() {
"quit" => {
app.exit(0);
}
"show" => {
if let Some(window) = app.get_webview_window("main") {
let _ = window.show();
}
}
"hide" => {
if let Some(window) = app.get_webview_window("main") {
let _ = window.hide();
}
}
_ => {
println!("menu item {:?} not handled", event.id);
}
})
.on_tray_icon_event(|tray, event| match event {
tauri::tray::TrayIconEvent::Click {
id: _,
position,
button,
..
} => match button {
tauri::tray::MouseButton::Left => {
println!("Left click");
tray.app_handle()
.emit("tray_mouseleftclick", position)
.unwrap();
}
tauri::tray::MouseButton::Right => {
println!("Right click");
tray.app_handle()
.emit("tray_contextmenu", position)
.unwrap();
}
_ => {}
},
tauri::tray::TrayIconEvent::Enter { position, .. } => {
tray.app_handle().emit("tray_mouseenter", position).unwrap();
}
tauri::tray::TrayIconEvent::Leave { position, .. } => {
tray.app_handle().emit("tray_mouseleave", position).unwrap();
}
_ => {}
})
.build(app)?;
Ok(())
}
在vue页面中触发图标周期性显隐
<script setup>
import { ref } from "vue";
import { TrayIcon } from "@tauri-apps/api/tray";
const flashTimer = ref(false);
const flashTray = async (bool) => {
let flag = true;
if (bool) {
TrayIcon.getById("tray").then(async (res) => {
clearInterval(flashTimer.value);
flashTimer.value = setInterval(() => {
if (flag) {
res.setIcon(null);
} else {
res.setIcon("tray/msg.png");
}
flag = !flag;
}, 500);
});
} else {
clearInterval(flashTimer.value);
let tray = await TrayIcon.getById("tray");
tray.setIcon("icons/icon.png");
}
};
</script>
<template>
<main class="container">
<h1>Welcome to Tauri + Vue</h1>
<div class="row">
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo vite" alt="Vite logo" />
</a>
<a href="https://tauri.app" target="_blank">
<img src="/tauri.svg" class="logo tauri" alt="Tauri logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="../assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div>
<p>Click on the Tauri, Vite, and Vue logos to learn more.</p>
<form class="row" @submit.prevent="greet">
<input id="greet-input" v-model="name" placeholder="Enter a name..." />
<button type="submit">Greet</button>
</form>
<div @click="flashTray(true)">托盘闪烁</div>
<div @click="flashTray(false)">关闭托盘闪烁</div>
</main>
</template>
<style scoped>
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #249b73);
}
</style>
<style>
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
input,
button {
outline: none;
}
#greet-input {
margin-right: 5px;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
button:active {
background-color: #0f0f0f69;
}
}
</style>
注意以上操作均需要在tauri中设置对应的权限,否则无法生效
ps: 个别的权限未设置,不会有任何报错
在capabilities中添加 权限 webview.json
{
"identifier": "webview",
"description": "Capability for the main window",
"windows": ["*"],
"permissions": [
"core:webview:allow-create-webview-window",
"core:webview:allow-create-webview",
"core:webview:allow-webview-close",
"core:webview:allow-create-webview-window"
]
}
和权限 window.json
{
"identifier": "window",
"description": "Capability for the main window",
"windows": ["*"],
"permissions": [
"core:window:default",
"core:window:allow-create",
"core:window:allow-center",
"core:window:allow-request-user-attention",
"core:window:allow-set-resizable",
"core:window:allow-set-maximizable",
"core:window:allow-set-minimizable",
"core:window:allow-set-closable",
"core:window:allow-set-title",
"core:window:allow-maximize",
"core:window:allow-unmaximize",
"core:window:allow-minimize",
"core:window:allow-unminimize",
"core:window:allow-show",
"core:window:allow-hide",
"core:window:allow-close",
"core:window:allow-destroy",
"core:window:allow-set-decorations",
"core:window:allow-set-always-on-top",
"core:window:allow-set-content-protected",
"core:window:allow-set-size",
"core:window:allow-set-min-size",
"core:window:allow-set-max-size",
"core:window:allow-set-position",
"core:window:allow-set-fullscreen",
"core:window:allow-set-focus",
"core:window:allow-set-icon",
"core:window:allow-set-skip-taskbar",
"core:window:allow-set-cursor-grab",
"core:window:allow-set-cursor-visible",
"core:window:allow-set-cursor-icon",
"core:window:allow-set-cursor-position",
"core:window:allow-set-ignore-cursor-events",
"core:window:allow-start-dragging"
]
}
以上即可实现Tauri托盘图标闪烁
ps: 参考代码待整理后会放到github