Shiny仪表板密码认证:内容无法绑定到对应标签页问题
解决shinydashboard结合shinyauthr时标签页内容绑定问题
我明白你遇到的问题了——你已经实现了登录认证,但标签页的内容没法正确切换,所有内容都堆在一起显示。这是因为你没有遵循shinydashboard的标准标签页结构,同时侧边栏菜单的写法也有问题。下面是修正后的完整代码,我会在后面解释关键修改点:
library(shiny) library(shinyauthr) library(shinyjs) library(shinydashboard) # 存储用户名、密码及其他用户数据的数据框 user_base <- data.frame( user = c("user1", "user2"), password = c("pass1", "pass2"), permissions = c("admin", "standard"), name = c("User One", "User Two"), stringsAsFactors = FALSE ) ui <- dashboardPage( dashboardHeader(title = "Hello"), dashboardSidebar( # 用一个sidebarMenu包裹所有menuItem,这是shinydashboard的标准写法 sidebarMenu( menuItem("Select Security", tabName = "select_security", icon = icon("lock")), menuItem("Portfolio", tabName = "portfolio", icon = icon("briefcase")) ) ), dashboardBody( shinyjs::useShinyjs(), # 登录和登出控件放在顶部 div(class = "pull-right", shinyauthr::logoutUI(id = "logout")), shinyauthr::loginUI(id = "login"), # 用shinydashboard的tabItems和tabItem来管理标签页内容,这是核心! tabItems( tabItem( tabName = "select_security", # 只有登录后才显示内容 conditionalPanel(condition = "output.user_auth", textOutput("welcome_note")) ), tabItem( tabName = "portfolio", conditionalPanel(condition = "output.user_auth", tableOutput("user_table")) ) ) ) ) server <- function(input, output, session) { # 初始化登出模块 logout_init <- callModule(shinyauthr::logout, id = "logout", active = reactive(credentials()$user_auth)) # 初始化登录模块,获取认证状态 credentials <- callModule(shinyauthr::login, id = "login", data = user_base, user_col = user, pwd_col = password, log_out = reactive(logout_init())) # 创建一个输出变量,用于conditionalPanel判断登录状态 output$user_auth <- reactive({ credentials()$user_auth }) outputOptions(output, "user_auth", suspendWhenHidden = FALSE) # 渲染欢迎信息,只有登录后才执行 output$welcome_note <- renderText({ req(credentials()$user_auth) paste0("Hello, ", credentials()$info$name, "!") }) # 渲染用户表格,这里用用户的权限数据做示例 output$user_table <- renderTable({ req(credentials()$user_auth) credentials()$info # 显示当前登录用户的信息 }) } shinyApp(ui = ui, server = server)
关键修改点说明:
修正侧边栏菜单结构:
原来你用了多个sidebarMenu,正确的做法是用一个sidebarMenu包裹所有menuItem,每个menuItem的tabName要和后面tabItem的tabName一一对应。使用shinydashboard标准标签页结构:
必须用tabItems包裹各个tabItem,把对应标签页的内容放在tabItem内部,这样点击侧边栏菜单时才会正确切换显示内容,而不是所有内容都同时显示。条件控制内容显示:
用conditionalPanel结合output.user_auth来控制标签页内容的显示,确保未登录时看不到任何业务内容,只有登录后才会显示。同时设置outputOptions(output, "user_auth", suspendWhenHidden = FALSE)保证这个输出变量始终处于活跃状态,让条件判断生效。优化登录后信息展示:
利用credentials()$info可以获取当前登录用户的详细数据,比如我在欢迎信息里加入了用户名,表格直接显示用户的权限信息,让内容更贴合实际需求。
这样修改后,你就能实现登录后切换标签页显示对应内容的效果了。
内容的提问来源于stack exchange,提问作者RoboHay
相关产品推荐
相关产品推荐

