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

如何在R Shiny中结合shiny.router实现二级导航栏?

实现shiny.router兼容二级导航的方案

1. 核心思路

放弃navbarPage/navbarMenu的整合尝试,手动构建Bootstrap风格的二级导航HTML结构,通过shiny.router的路由函数绑定导航链接,既保留路由的多页面管理能力,又能自由维护层级清晰的导航菜单,完全避开tabPanel的代码冗余问题。

2. 具体代码实现

第一步:定义各页面UI

先把需要的页面模块单独写好,方便后续扩展:

# 首页
home_page <- function() {
  fluidPage(h1("教材首页"))
}

# 第一章子页面1
chap1_page1 <- function() {
  fluidPage(h2("第一章 - 统计基础概念"))
}

# 第一章子页面2
chap1_page2 <- function() {
  fluidPage(h2("第一章 - 数据预处理"))
}

# 第二章子页面1
chap2_page1 <- function() {
  fluidPage(h2("第二章 - 线性回归模型"))
}

# 第二章子页面2
chap2_page2 <- function() {
  fluidPage(h2("第二章 - 模型诊断"))
}

第二步:配置路由规则

用shiny.router::make_router建立路径和页面的对应关系:

library(shiny)
library(shiny.router)

router <- make_router(
  route("/", home_page()),
  route("/chap1/concepts", chap1_page1()),
  route("/chap1/preprocess", chap1_page2()),
  route("/chap2/regression", chap2_page1()),
  route("/chap2/diagnosis", chap2_page2())
)

第三步:手动编写二级导航栏

基于Bootstrap的下拉菜单组件写导航结构,每个链接用shiny.router::href()生成对应路由地址:

custom_navbar <- function() {
  tags$nav(class = "navbar navbar-expand-lg navbar-dark bg-primary",
    tags$a(class = "navbar-brand", href = href("/"), "统计教材网站"),
    # 移动端折叠按钮
    tags$button(class = "navbar-toggler", type = "button", `data-toggle` = "collapse", `data-target` = "#mainNav",
      tags$span(class = "navbar-toggler-icon")
    ),
    tags$div(class = "collapse navbar-collapse", id = "mainNav",
      tags$ul(class = "navbar-nav mr-auto",
        # 首页项
        tags$li(class = "nav-item",
          tags$a(class = "nav-link", href = href("/"), "首页")
        ),
        # 第一章下拉菜单
        tags$li(class = "nav-item dropdown",
          tags$a(class = "nav-link dropdown-toggle", href = "#", role = "button", `data-toggle` = "dropdown", "第一章"),
          tags$div(class = "dropdown-menu",
            tags$a(class = "dropdown-item", href = href("/chap1/concepts"), "统计基础概念"),
            tags$a(class = "dropdown-item", href = href("/chap1/preprocess"), "数据预处理")
          )
        ),
        # 第二章下拉菜单
        tags$li(class = "nav-item dropdown",
          tags$a(class = "nav-link dropdown-toggle", href = "#", role = "button", `data-toggle` = "dropdown", "第二章"),
          tags$div(class = "dropdown-menu",
            tags$a(class = "dropdown-item", href = href("/chap2/regression"), "线性回归模型"),
            tags$a(class = "dropdown-item", href = href("/chap2/diagnosis"), "模型诊断")
          )
        )
      )
    )
  )
}

第四步:整合到Shiny应用

把导航栏和路由输出组合,补充Bootstrap依赖确保下拉菜单正常工作:

ui <- fluidPage(
  tags$head(
    # 加载Bootstrap样式和交互脚本
    tags$link(rel = "stylesheet", href = "https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"),
    tags$script(src = "https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"),
    tags$script(src = "https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js")
  ),
  custom_navbar(),
  # 路由页面的输出容器
  router$ui
)

server <- function(input, output, session) {
  router$server(input, output, session)
}

shinyApp(ui, server)

3. 维护说明

后续新增章节或页面时,只需三步:

  • 新增对应页面的UI函数
  • 在make_router中添加新的route()规则
  • 在custom_navbar里新增下拉菜单或菜单项,结构清晰易维护

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:18:10