惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Cloudflare Blog
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Tailwind CSS Blog
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
博客园 - 司徒正美
V
Visual Studio Blog
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
aimingoo的专栏
aimingoo的专栏
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
D
Docker
Vercel News
Vercel News
Recent Announcements
Recent Announcements
Last Week in AI
Last Week in AI
爱范儿
爱范儿
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏

姓王者的博客

Linux用户Secure Boot自主维护指南 | 姓王者的博客 MAD Bugs 已经开始——关于信息安全的军备竞赛 | 姓王者的博客 解决钉钉Dingtalk无法在Linux新版内核上启动问题-修复可执行栈错误 | 姓王者的博客 突发:GitHub 正遭受大规模 Issue 赌博广告轰炸 | 姓王者的博客 Ubuntu26.04-beta体验:坚毅浣熊! | 姓王者的博客 fakeclaw装作龙虾发贴吧 | 姓王者的博客 找回12年前的QQ记忆 | 姓王者的博客 在Linux上玩Flash网页游戏-洛克王国 | 姓王者的博客 Copilot将使用交互数据来训练 | 姓王者的博客 重要通知-请更新我的GPG公钥 | 姓王者的博客 为了自由Android | 姓王者的博客 GPL"2,3"事 | 姓王者的博客 短文-对VitePlus的一点🤏小贡献 | 姓王者的博客 Bing收录没了?亲测有效的快速恢复指南 | 姓王者的博客 解决桌面设备二维码快速识别的工具-ClipQR | 姓王者的博客 解决 Nautilus 自定义终端插件安装依赖问题 | 姓王者的博客 OpenClaw 该熄火了 | 姓王者的博客 Vite8 - 统一的基建开始 | 姓王者的博客 Astro 6 推出啦 | 姓王者的博客 ubuntu的openvpn异常暂停推送更新 | 姓王者的博客 Ubuntu 24.04 安装 Win10 虚拟机 | 姓王者的博客 ESA-后记:热爱阿里云 | 姓王者的博客 Moonbit 0.8.0 重大发布,我也要改一下我的包 | 姓王者的博客 ESA Pages 边缘开发大赛获奖 | 姓王者的博客 Astro: 优化katex,mermaid和灯箱使用 | 姓王者的博客 从edgeone迁移到esa | 姓王者的博客 出租人类:AI时代的荒诞与真实 | 姓王者的博客 Astro 5.17构建性能优化实践:从18s到13s | 姓王者的博客 Moonbit License Checker 开发使用 | 姓王者的博客 Stalux Astro博客主题自荐 | 姓王者的博客
Tauri2.x实现系统菜单导航Vue路由 | 姓王者的博客
作者:xingwangzhe · 2025-09-21 · via 姓王者的博客

🕒 阅读时间:2 分钟 📝 字数:475 👀 阅读量: Loading...

本文介绍如何在 Tauri 2 应用中使用系统菜单控制 Vue 路由切换。过程涉及在 Rust 后端设置菜单,并通过事件发射处理前端的路由变更。

方法

在应用启动时,在 src-tauri/src/lib.rs 中使用 Tauri’s MenuBuilder 配置菜单。添加菜单项如“Editor”、“About”和“Settings”,每个项有唯一 ID 如“nav-home”用于识别。

设置监听器处理菜单事件。当用户点击菜单项时,on_menu_event 被触发,根据菜单 ID 发射名为“change_router”的自定义事件,并附带相应路由路径作为数据。

mod commands;

use tauri::menu::MenuBuilder;

use tauri::Emitter;

#[cfg_attr(mobile, tauri::mobile_entry_point)]

pub fn run() {

tauri::Builder::default()

.plugin(tauri_plugin_opener::init())

.invoke_handler(tauri::generate_handler![])

.setup(|app| {

let menu = MenuBuilder::new(app)

.text("nav-home", "Editor")

.text("nav-about", "About")

.text("nav-settings", "Settings")

.build()?;

app.set_menu(menu.clone())?;

app.on_menu_event(move |app_handle: &tauri::AppHandle, event| {

println!("menu event: {:?}", event.id());

match event.id().0.as_str() {

"nav-home" => {

println!("nav-home");

app_handle.emit("change_router", "/").unwrap()

}

"nav-about" => {

println!("nav-about");

app_handle.emit("change_router", "/about").unwrap()

}

"nav-settings" => {

println!("nav-settings");

app_handle.emit("change_router", "/settings").unwrap()

}

_ => {

println!("nothing")

}

}

});

Ok(())

})

.run(tauri::generate_context!())

.expect("error while running tauri application");

}

菜单是原生系统组件,因此在后端处理而非前端。事件发射实现了前后端的解耦,使前端专注于视图更新。

前端监听与响应

在前端 src/main.ts 中,使用 Vue Router 设置路由,包括首页、关于页和设置页。

关键是监听后端发来的“change_router”事件。收到事件后,调用 router.push({ path: event.payload }) 切换路由。使用对象格式传递路径,以符合 Vue Router 的类型要求,避免 TypeScript 类型错误。

import { createApp } from "vue";

import App from "./App.vue";

import { createMemoryHistory, createRouter } from "vue-router";

import { listen } from "@tauri-apps/api/event";

import Home from "./pages/Home.vue";

import About from "./pages/About.vue";

import Settings from "./pages/Settings.vue";

const routes = [

{ path: "/", component: Home },

{ path: "/about", component: About },

{ path: "/settings", component: Settings },

];

const router = createRouter({

history: createMemoryHistory(),

routes,

});

listen<String>("change_router", (event) => {

console.log(event.payload);

router.push({ path: event.payload });

});

createApp(App).use(router).mount("#app");

前端代码保持简洁,通过事件与后端通信,而不直接操作菜单。这种设计提高了模块化和可维护性。

效果

切换路由

在我Ubuntu 24.04LTS上的效果

完整过程

应用启动时,后端创建菜单并分配到窗口。当用户点击菜单项如“Editor”时,后端监听器检测事件并发射“change_router”事件,附带路径“/”。前端收到事件后,使用路由器更新视图为 Home 组件。过程高效,提供原生应用体验。

Tauri 2 与 Vue Router 的集成允许后端管理菜单,前端处理路由,通过事件实现通信。

题外话

TaurI前后端通信真好玩😋