You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yew框架点击Route Link时如何添加.is-active导航CSS类

Yew + Bulma 导航栏激活样式实现方案

不需要拦截Link组件的点击事件,这种实现方式覆盖场景不全,维护成本高。yew-router 内置了获取当前激活路由的Hook,直接基于当前路由判断是否给导航项添加is-active类即可,能自动适配所有路由跳转场景:点击链接、浏览器前进/后退、地址栏直接输入、代码主动触发路由跳转都能正确显示激活状态。

实现步骤

  • 在组件内调用use_route::<AppRoutes>()获取当前匹配的路由,路由发生变化时组件会自动重渲染,不需要手动监听事件
  • 将原代码中控制移动端汉堡菜单、折叠菜单展开状态的active_class重命名(比如改为mobile_menu_active_class),避免和导航项激活类的变量名冲突
  • 每个导航Link的classes属性中增加判断逻辑:当前路由和Link指向的路由一致时,追加is-active样式类

修改后的完整代码

use yew::prelude::*;
use yew_router::prelude::*;

use crate::routes::app_routes::AppRoutes;

#[function_component]
pub fn Nav() -> Html {
    let navbar_menu_open = use_state_eq(|| false);
    // 获取当前激活的路由,路由变化时自动触发组件重渲染
    let current_route = use_route::<AppRoutes>();

    let toggle_navbar = {
        let navbar_menu_open = navbar_menu_open.clone();
        Callback::from(move |_| {
            navbar_menu_open.set(!*navbar_menu_open);
        })
    };

    // 移动端汉堡菜单/折叠菜单的激活类
    let mobile_menu_active_class = if *navbar_menu_open { "is-active" } else { "" };

    html! {
        <nav class="navbar is-primary" role="navigation" aria-label="main navigation">
            <div class="navbar-brand">
                <h1 class="navbar-item is-size-3">{ "UVW" }</h1>

                <button class={classes!("navbar-burger", "burger", mobile_menu_active_class)}
                    aria-label="menu" aria-expanded="false"
                    onclick={toggle_navbar}
                >
                    <span aria-hidden="true"></span>
                    <span aria-hidden="true"></span>
                    <span aria-hidden="true"></span>
                </button>
            </div>
            <div class={classes!("navbar-menu", mobile_menu_active_class)}>
                <div class="navbar-start">
                    <Link<AppRoutes> 
                        classes={classes!(
                            "navbar-item",
                            // 当前路由匹配Home时追加is-active类
                            (current_route == Some(AppRoutes::Home)).then_some("is-active")
                        )} 
                        to={AppRoutes::Home}
                    >
                        { "Home" }
                    </Link<AppRoutes>>

                    <Link<AppRoutes> 
                        classes={classes!(
                            "navbar-item",
                            (current_route == Some(AppRoutes::About)).then_some("is-active")
                        )} 
                        to={AppRoutes::About}
                    >
                        { "About" }
                    </Link<AppRoutes>>

                    <div class="navbar-item has-dropdown is-hoverable">
                        <div class="navbar-link">
                            { "More" }
                        </div>
                        <div class="navbar-dropdown">
                            <Link<AppRoutes> 
                                classes={classes!(
                                    "navbar-item",
                                    (current_route == Some(AppRoutes::Home)).then_some("is-active")
                                )} 
                                to={AppRoutes::Home}
                            >
                                { "DropDown1" }
                            </Link<AppRoutes>>
                            <Link<AppRoutes> 
                                classes={classes!(
                                    "navbar-item",
                                    // 替换为对应下拉项实际指向的路由即可
                                    (current_route == Some(AppRoutes::Home)).then_some("is-active")
                                )} 
                                to={AppRoutes::Home}
                            >
                                { "DropDown2" }
                            </Link<AppRoutes>>
                            <Link<AppRoutes> 
                                classes={classes!(
                                    "navbar-item",
                                    (current_route == Some(AppRoutes::Home)).then_some("is-active")
                                )} 
                                to={AppRoutes::Home}
                            >
                                { "DropDown3" }
                            </Link<AppRoutes>>
                        </div>
                    </div>
                </div>
            </div>
        </nav>
    }
}

注:代码中顺便修正了原实现里移动端菜单的逻辑错误:原代码激活类判断条件写反,会导致页面首次加载时汉堡按钮默认为激活状态、移动端菜单默认展开。

如果编译报错提示AppRoutes未实现PartialEq,在路由枚举的派生宏中补充该trait即可,示例:

#[derive(Debug, Clone, PartialEq, Routable)]
pub enum AppRoutes {
    #[at("/")]
    Home,
    #[at("/about")]
    About,
    // 其余业务路由定义
}

内容的提问来源于stack exchange,提问作者tempbottle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:36:28