SxAppShell (应用外壳)
- Implemented
提供响应式应用基础布局,包含侧边栏、顶部导航栏和主内容区域。支持自动响应式切换、内部导航、多 Tab 历史栈等高级功能。
使用场景
- 应用级响应式布局(桌面/移动端自适应)
- 侧边栏 + 顶部导航栏布局
- 单页应用(SPA)内部导航
- 多 Tab 页面缓存与历史管理
基本用法
最简单的用法
<SxAppRoot>
<SxAppShell TitleText="我的应用">
<Navigation>
<SxNavMenu>
<SxNavMenuLink Text="首页" IconName="house" Href="/" />
<SxNavMenuLink Text="设置" IconName="gear" Href="/settings" />
</SxNavMenu>
</Navigation>
<Content>
@(context => @<div>主内容区域</div>)
</Content>
</SxAppShell>
</SxAppRoot>
完整示例
<SxAppRoot>
<SxAppShell TitleText="企业管理系统"
ShowCollapseToggle="true"
@bind-Collapsed="_collapsed"
SizingMode="SxAppShellSizingMode.Viewport"
BreakpointChanged="OnBreakpointChanged">
<Navigation>
@RenderNavigation
</Navigation>
<Content>
@(isWide => @<div class="@(isWide ? "wide-layout" : "narrow-layout")">
@Body
</div>)
</Content>
</SxAppShell>
</SxAppRoot>
@code {
private bool _collapsed;
private RenderFragment RenderNavigation => __builder =>
{
<SxNavMenu>
<SxNavMenuGroup Text="用户管理" IconName="users">
<SxNavMenuLink Text="用户列表" Href="/users" />
<SxNavMenuLink Text="角色管理" Href="/roles" />
</SxNavMenuGroup>
<SxNavMenuLink Text="系统设置" IconName="gear" Href="/settings" />
</SxNavMenu>
};
private void OnBreakpointChanged(SxAppShell.Breakpoint breakpoint)
{
Console.WriteLine($"断点变化: {breakpoint}");
}
}
布局模式
SxAppShell 支持三种布局模式,通过 LayoutMode 参数控制:
自动模式(默认)
<SxAppShell LayoutMode="null">
<!-- 宽屏(LG/XL)使用侧边栏,窄屏(XS/SM/MD)使用抽屉 -->
</SxAppShell>
- 宽屏(≥LG):固定侧边栏 + 可拖拽分割条
- 窄屏(<LG):抽屉式导航 + 汉堡菜单按钮
强制侧边栏模式
<SxAppShell LayoutMode="SxAppShellLayoutMode.Sidebar">
<!-- 始终使用侧边栏布局,即使在移动端 -->
</SxAppShell>
强制抽屉模式
<SxAppShell LayoutMode="SxAppShellLayoutMode.Drawer">
<!-- 始终使用抽屉布局,侧边显示窄条(Rail) -->
</SxAppShell>
响应式断点
默认断点
| 断点 | 宽度 | 布局行为 |
|---|---|---|
| XS | < 576px | 抽屉模式,侧边栏完全隐藏 |
| SM | ≥ 576px | 抽屉模式,侧边栏完全隐藏 |
| MD | ≥ 768px | 抽屉模式,显示窄条(Rail) |
| LG | ≥ 992px | 侧边栏模式 |
| XL | ≥ 1200px | 侧边栏模式 |
自定义断点
<SxAppShell BreakpointConfig="@_breakpointConfig">
...
</SxAppShell>
@code {
private SxAppShellBreakpointConfig _breakpointConfig = new()
{
XS = "0px",
SM = "480px",
MD = "768px",
LG = "1024px",
XL = "1280px"
};
}
容器尺寸模式
默认情况下,断点基于视口(Viewport)宽度计算。如果 SxAppShell 嵌入在容器中,可以使用容器尺寸:
<div style="width: 800px; height: 600px;">
<SxAppShell SizingMode="SxAppShellSizingMode.Container">
<!-- 断点基于容器宽度而非视口宽度 -->
</SxAppShell>
</div>
侧边栏折叠
基本折叠控制
<SxAppShell @bind-Collapsed="_collapsed"
ShowCollapseToggle="true">
...
</SxAppShell>
@code {
private bool _collapsed;
private void ExpandSidebar() => _collapsed = false;
private void CollapseSidebar() => _collapsed = true;
}
折叠宽度
<SxAppShell Collapsed="true"
CollapsedWidth="60px">
<!-- 折叠时侧边栏宽度为 60px -->
</SxAppShell>
窄条(Rail)显示控制
<!-- 自动:MD 及以上显示窄条,SM/XS 隐藏 -->
<SxAppShell CollapsedRailMode="SxAppShellCollapsedRailMode.Auto" />
<!-- 始终显示窄条 -->
<SxAppShell CollapsedRailMode="SxAppShellCollapsedRailMode.Show" />
<!-- 始终隐藏窄条 -->
<SxAppShell CollapsedRailMode="SxAppShellCollapsedRailMode.Hidden" />
始终显示侧边栏
在小屏幕上也保持显示折叠的侧边栏(窄条):
<SxAppShell AlwaysShowSidebar="true">
<!-- 即使在 XS/SM 断点也显示窄条 -->
</SxAppShell>
折叠时显示内容区导航栏
<!-- 默认行为:折叠时在内容区顶部显示导航栏 -->
<SxAppShell Collapsed="true" ShowContentNavBarWhenCollapsed="true" />
<!-- 禁用:折叠时不显示内容区导航栏 -->
<SxAppShell Collapsed="true" ShowContentNavBarWhenCollapsed="false" />
抽屉遮罩
控制抽屉展开时的遮罩层行为:
<!-- 透明遮罩,点击可关闭抽屉 -->
<SxAppShell DrawerOverlayMode="SxAppShellDrawerOverlayMode.Transparent" />
<!-- 隐藏遮罩,抽屉不遮挡内容区 -->
<SxAppShell DrawerOverlayMode="SxAppShellDrawerOverlayMode.Hidden" />
自定义导航栏
使用 NavBarTemplate
NavBarTemplate 参数接收一个布尔值,表示当前是否为侧边栏模式:
<SxAppShell>
<NavBarTemplate>
@{ var isSidebarMode = context; }
<SxNavBar TitleText="我的应用"
IsSidebarMode="@isSidebarMode"
ShowHamburger="@isSidebarMode">
<LeftActions>
@if (!isSidebarMode)
{
<SxButton Appearance="ButtonAppearance.Stealth"
IconStart="bars"
OnClick="ToggleSidebar" />
}
</LeftActions>
<FunctionalMenu>
<SxMenuItem Text="设置" Icon="gear" />
<SxMenuItem Text="退出" Icon="sign-out" />
</FunctionalMenu>
</SxNavBar>
</NavBarTemplate>
<Navigation>
<SxNavMenu>...</SxNavMenu>
</Navigation>
</SxAppShell>
自定义导航菜单
<SxAppShell>
<Navigation>
<SxNavMenu>
<!-- 普通链接 -->
<SxNavMenuLink Text="首页" IconName="house" Href="/" />
<!-- 分组 -->
<SxNavMenuGroup Text="用户管理" IconName="users" DefaultOpen="true">
<SxNavMenuLink Text="用户列表" Href="/users" />
<SxNavMenuLink Text="角色管理" Href="/roles" />
<SxNavMenuLink Text="权限设置" Href="/permissions" />
</SxNavMenuGroup>
<!-- 带徽标 -->
<SxNavMenuLink Text="消息" IconName="envelope" Href="/messages">
<Badge>
<SxBadge>5</SxBadge>
</Badge>
</SxNavMenuLink>
<!-- 分隔线 -->
<SxNavMenuDivider />
<!-- 外部链接 -->
<SxNavMenuLink Text="帮助文档"
IconName="question-circle"
Href="https://docs.example.com"
Target="_blank" />
</SxNavMenu>
</Navigation>
</SxAppShell>
底部栏 (BottomBar)
SxAppShell 提供了一个 BottomBar RenderFragment 插槽,用于在侧边栏底部放置固定内容。这是一个通用容器,可以放置任意组件,最常见的用途是放置 SxUserBar 用户栏组件。
设计理念
- 容器与内容分离:BottomBar 只是一个容器,不包含业务逻辑
- 固定定位:BottomBar 固定在侧边栏底部,不随导航内容滚动
- 毛玻璃效果:内置半透明背景和模糊效果,滚动内容从其下方穿过
- 灵活组合:可放置 SxUserBar、自定义按钮或任何其他组件
基本用法
<SxAppShell>
<Navigation>
<SxNavMenu>
<SxNavMenuLink Text="首页" IconName="house" Href="/" />
<SxNavMenuLink Text="设置" IconName="gear" Href="/settings" />
</SxNavMenu>
</Navigation>
<BottomBar>
<SxUserBar UserName="张三"
UserSubtitle="admin@example.com"
UserPresence="AvatarPresence.Online"
OnLogout="HandleLogout"
OnSettings="HandleSettings" />
</BottomBar>
</SxAppShell>
@code {
private async Task HandleLogout()
{
await AuthService.LogoutAsync();
NavigationManager.NavigateTo("/login");
}
private void HandleSettings()
{
NavigationManager.NavigateTo("/settings");
}
}
SxUserBar 配置
SxUserBar 是一个独立组件,自动响应 SxAppShell 的折叠状态:
<SxAppShell @bind-Collapsed="_collapsed">
<Navigation>...</Navigation>
<BottomBar>
<SxUserBar UserName="张三"
UserSubtitle="admin@example.com"
UserAvatarUrl="/avatars/user.jpg"
ShowSettings="true"
ShowQuickSettings="true"
ShowLogout="true"
OnLogout="HandleLogout"
OnSettings="HandleSettings"
OnUserClick="HandleUserClick">
<MenuContent>
<!-- 自定义菜单项(显示在内置项之前) -->
<SxMenuItem Text="我的订单" Icon="shopping-cart" OnClick="..." />
<SxMenuItem Text="消息中心" Icon="bell" OnClick="..." />
<SxMenuDivider />
</MenuContent>
</SxUserBar>
</BottomBar>
</SxAppShell>
SxUserBar 参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
UserName |
string? |
"User" |
用户名 |
UserSubtitle |
string? |
null |
副标题(邮箱/角色) |
UserAvatarUrl |
string? |
null |
头像 URL |
UserPresence |
AvatarPresence |
None |
在线状态(默认不显示) |
MenuContent |
RenderFragment? |
null |
自定义菜单项 |
ShowSettings |
bool |
true |
显示设置菜单项 |
ShowQuickSettings |
bool |
true |
显示快捷设置(主题/语言) |
ShowLogout |
bool |
true |
显示退出登录菜单项 |
OnLogout |
EventCallback |
退出登录点击事件 | |
OnSettings |
EventCallback |
设置点击事件 | |
OnUserClick |
EventCallback |
用户信息区域点击事件 |
交互行为
SxUserBar 分为两个独立的可点击区域:
- 用户信息区域(头像 + 用户名):点击触发
OnUserClick事件,可用于跳转到用户资料页 - 箭头按钮:点击弹出菜单,箭头图标会旋转指示菜单状态
<SxUserBar UserName="张三"
OnUserClick="@(() => Nav.NavigateTo("/profile"))"
OnLogout="HandleLogout"
OnSettings="HandleSettings" />
折叠状态适配
SxUserBar 通过 CascadingParameter 接收 SxAppShellContext,自动响应折叠状态:
- 展开状态:显示头像、用户名、副标题和箭头按钮
- 折叠状态:仅显示头像,点击头像弹出菜单
自定义底部栏内容
BottomBar 可以放置任意内容,不限于 SxUserBar:
<SxAppShell>
<Navigation>...</Navigation>
<BottomBar>
<!-- 自定义底部栏:版本信息 -->
<div style="padding: var(--sx-spacing-m) var(--sx-shell-rail-pad-x); text-align: center;">
<SxTypography Variant="TypographyVariant.Caption">v1.0.0</SxTypography>
</div>
</BottomBar>
</SxAppShell>
毛玻璃效果
BottomBar 容器自带毛玻璃效果(backdrop-filter),当导航菜单滚动时,内容会从底部栏下方透过:
.sx-sidebar-bottom-bar {
background: color-mix(in srgb, var(--sx-colorNeutralBackground2) 80%, transparent);
backdrop-filter: blur(12px);
}
内部导航
SxAppShell 支持内部导航模式,页面切换在外壳内部完成,不触发浏览器导航。
基于 NavigationContent
<SxAppShell NavigationMode="SxAppShellNavigationMode.Internal"
InitialRoute="/dashboard"
OnNavigate="HandleNavigate">
<Navigation>
<SxNavMenu>
<SxNavMenuLink Text="仪表盘" IconName="chart-line" Href="/dashboard" />
<SxNavMenuLink Text="用户" IconName="users" Href="/users" />
</SxNavMenu>
</Navigation>
<NavigationContent>
@{ var route = context; }
@switch (route)
{
case "/dashboard":
<DashboardPage />
break;
case "/users":
<UsersPage />
break;
default:
<NotFoundPage />
break;
}
</NavigationContent>
</SxAppShell>
@code {
private void HandleNavigate(string? route)
{
Console.WriteLine($"导航到: {route}");
}
}
基于路由程序集
<SxAppShell NavigationMode="SxAppShellNavigationMode.Auto"
RouteAppAssembly="@typeof(Program).Assembly"
InitialRoute="/dashboard">
<Navigation>
<SxNavMenu>
<SxNavMenuLink Text="仪表盘" Href="/dashboard" />
<SxNavMenuLink Text="用户" Href="/users" />
</SxNavMenu>
</Navigation>
</SxAppShell>
浏览器 URL 同步
<!-- 默认:同步浏览器 URL -->
<SxAppShell SyncBrowserUrl="true" />
<!-- 禁用同步(适用于嵌套或演示场景) -->
<SxAppShell SyncBrowserUrl="false" />
历史栈限制
<SxAppShell MaxHistoryDepth="10"
MaxCachedPages="20">
<!-- 每个 Tab 最多保留 10 条历史记录 -->
<!-- 全局最多缓存 20 个页面 -->
</SxAppShell>
两种导航模式对比
SxAppShell 提供两种主要的内容渲染方式:
| 特性 | Content + @Body |
RouteAppAssembly |
|---|---|---|
| 路由处理 | 由外层 Blazor <Router> 处理 |
SxAppShell 内部接管 |
| 页面生命周期 | 切换时销毁旧页面、创建新页面 | 页面保留在 DOM 中(display:none) |
| 状态保持 | 不支持 | 支持(表单值、滚动位置等完整保留) |
| 历史栈 | 无 | 每个导航节点独立维护 |
| 需要 LayoutComponentBase | 是 | 否 |
| 需要外层 Router | 是 | 否 |
| 适用场景 | 简单应用,或已有 Blazor Router 体系 | 复杂应用、MAUI Hybrid、需要状态保持 |
Content + @Body 模式
传统模式,MainLayout 继承 LayoutComponentBase,由 Blazor Router 做路由匹配并通过 @Body 渲染:
@inherits LayoutComponentBase
<SxAppShell>
<Content>
<div class="my-content">@Body</div>
</Content>
</SxAppShell>
每次侧边栏切换都会销毁旧页面组件、创建新组件,页面状态(如表单输入、滚动位置)会丢失。
RouteAppAssembly 模式
SxAppShell 接管路由渲染,内部使用 SxRouteView 做路由匹配和页面管理:
<SxAppShell RouteAppAssembly="@typeof(Routes).Assembly"
RouteFound="@RenderRouteContent"
RouteNotFound="@RenderNotFound"
InitialRoute="/">
<Navigation>...</Navigation>
</SxAppShell>
@code {
private RenderFragment<RouteData> RenderRouteContent => routeData => __builder =>
{
<div class="my-content">
<RouteView RouteData="@routeData" />
</div>
};
private RenderFragment RenderNotFound => __builder =>
{
<SxTypography Variant="TypographyVariant.H3">Page Not Found</SxTypography>
};
}
页面状态保持原理
启用 RouteAppAssembly 后,页面切换行为如下:
- 首次访问:创建页面组件实例,渲染到 DOM
- 离开页面:组件实例和 DOM 保留,通过
display:none隐藏 - 再次访问:直接显示缓存的页面,不重新创建组件
- 堆栈管理:每个侧边栏导航节点对应独立的 Tab 堆栈,深入子页面后返回时状态完整保留
侧边栏节点间的状态保持:在不同导航节点之间切换时,每个节点的页面状态互不影响、各自保留。具体来说:
- 页面组件不销毁:从「设备信息」切到「诊断中心」时,「设备信息」的组件实例仍然存活,只是所在 DOM 被设置为
display:none - 表单值、滚动位置、组件内部状态全部保留:切回时页面恢复到离开时的状态
- 子页面堆栈独立:在「设备信息」中深入到子页面后切换到其他节点,再切回时子页面堆栈完整保留
这是 RouteAppAssembly 模式与 Content+@Body 模式的核心区别——后者每次侧边栏切换都会销毁旧页面组件、创建新组件,所有临时状态丢失。
缓存限制与超限行为
默认情况下,所有导航节点和历史记录不设限制,全部保留在内存中。通过以下参数控制资源占用:
| 参数 | 类型 | 默认值 | 作用域 |
|---|---|---|---|
MaxHistoryDepth |
int? |
null(无限制) |
单个 Tab 堆栈 |
MaxCachedPages |
int? |
null(无限制) |
全局(跨所有 Tab) |
MaxHistoryDepth — 限制单个 Tab 内的历史深度。当某个 Tab 的历史条目数超过此值时,最早的条目(栈底)被移除,对应页面组件销毁。下次导航到该路由时页面将重新创建(状态丢失)。
MaxCachedPages — 限制所有 Tab 缓存的页面总数。超限时按 LRU(最近最少使用)策略淘汰:
- 收集所有 Tab 中的全部页面条目,按最后活跃时间排序
- 从最久未访问的条目开始淘汰,当前各 Tab 的活跃页面不会被淘汰
- 被淘汰的页面组件销毁,下次导航到时重新渲染
导航节点(Tab)数量没有上限参数,侧边栏有多少个菜单项就会创建多少个 Tab。限制的是每个 Tab 内部的历史深度和全局的缓存页面总数。
<!-- 推荐:页面较多的应用设置合理限制 -->
<SxAppShell MaxHistoryDepth="10"
MaxCachedPages="20"
RouteAppAssembly="@typeof(Routes).Assembly">
...
</SxAppShell>
注意事项
- 不要同时使用两种模式:设置了
RouteAppAssembly后,不要同时设置Content参数,否则Content会被忽略 - 不需要外层 Router:
RouteAppAssembly模式下,SxAppShell 内部已包含路由匹配逻辑,不需要在外层用<Router>包裹 - TabKey 自定义分组:每个侧边栏节点自动对应一个独立 Tab 堆栈。如需自定义分组,可通过
SxNavMenuLink的TabKey属性指定 - InitialRoute 建议设置:不提供
InitialRoute时首次加载可能显示空白,建议始终指定默认路由 - RouteFound 可选:如果不提供
RouteFound,SxAppShell 使用默认的<RouteView>渲染。自定义RouteFound可以包裹额外的布局容器
从 Content 迁移到 RouteAppAssembly
步骤 1:修改 MainLayout
- @inherits LayoutComponentBase
<SxAppShell Navigation="@RenderNav"
- ...>
- <Content>
- <div class="my-content">@Body</div>
- </Content>
+ InitialRoute="/"
+ RouteAppAssembly="@typeof(Routes).Assembly"
+ RouteFound="@RenderRouteContent"
+ RouteNotFound="@RenderNotFound"
+ ...>
</SxAppShell>
+ @code {
+ private RenderFragment<RouteData> RenderRouteContent => routeData => __builder =>
+ {
+ <div class="my-content">
+ <RouteView RouteData="@routeData" />
+ </div>
+ };
+
+ private RenderFragment RenderNotFound => __builder =>
+ {
+ <SxTypography Variant="TypographyVariant.H3">Page Not Found</SxTypography>
+ };
+ }
步骤 2:简化 Routes.razor
- <Router AppAssembly="typeof(Routes).Assembly">
- <Found Context="routeData">
- <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
- </Found>
- <NotFound>
- <LayoutView Layout="typeof(MainLayout)">
- <p>Page not found.</p>
- </LayoutView>
- </NotFound>
- </Router>
+ <MainLayout />
步骤 3:验证
- 编译通过
- 侧边栏导航切换后页面状态保持
- 浏览器 URL 跟随导航同步更新
- 深入子页面后返回时状态完整保留
Blazor Server 预渲染
ServerPrerendered 模式
在使用 render-mode="ServerPrerendered" 时,必须为 SxAppShell 提供稳定的 Id 参数,以确保服务端预渲染和客户端水合使用相同的 ID:
<!-- _Layout.cshtml -->
<body>
<component type="typeof(AppShell)" render-mode="ServerPrerendered" />
<script src="/_framework/blazor.server.js"></script>
</body>
<!-- AppShell.razor -->
<SxAppRoot>
<SxAppShell Id="main-shell"
ShowCollapseToggle="true"
@bind-Collapsed="_collapsed"
TitleText="我的应用">
<Navigation>
<SxNavMenu>
<SxNavMenuLink Text="首页" IconName="house" Href="/" />
</SxNavMenu>
</Navigation>
<Content>
@(isWide => @<main id="content-slot"></main>)
</Content>
</SxAppShell>
</SxAppRoot>
@code {
private bool _collapsed;
}
注意事项
- 必须提供
Id参数:避免预渲染和水合时 ID 不一致导致事件处理器失效 - 确保服务注册:
IUserPreferences、INavStackService等服务必须在 DI 容器中注册 - 避免依赖 JS 初始状态:断点检测等 JS 功能在预渲染时不可用,组件会在水合后初始化
不同渲染模式对比
| 渲染模式 | 描述 | 注意事项 |
|---|---|---|
ServerPrerendered |
HTML 预渲染 + SignalR 交互 | 需要稳定 Id |
Server |
仅 SignalR 交互 | 无预渲染闪烁,首屏稍慢 |
WebAssembly |
客户端渲染 | 无特殊注意事项 |
WebAssemblyPrerendered |
HTML 预渲染 + WASM 交互 | 需要稳定 Id |
嵌套 Shell
SxAppShell 支持嵌套使用(如演示场景)。嵌套的 Shell 会自动禁用浏览器 URL 同步:
<SxAppShell Id="outer-shell">
<Content>
@(isWide => @<div class="demo-container">
<!-- 嵌套的 Shell,不会影响浏览器 URL -->
<SxAppShell Id="inner-shell"
SyncBrowserUrl="false"
SizingMode="SxAppShellSizingMode.Container">
...
</SxAppShell>
</div>)
</Content>
</SxAppShell>
API
Parameters
| 参数名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
Id |
string? |
null |
组件 ID,ServerPrerendered 模式必须提供 |
Navigation |
RenderFragment? |
null |
侧边栏导航内容 |
NavBarTemplate |
RenderFragment<bool>? |
null |
导航栏模板(参数为是否侧边栏模式) |
Content |
RenderFragment<bool>? |
null |
主内容模板(参数为是否宽屏) |
TitleText |
string? |
null |
默认导航栏标题文本 |
ShowCollapseToggle |
bool |
true |
是否显示内置折叠切换按钮 |
Collapsed |
bool |
false |
侧边栏折叠状态 |
CollapsedWidth |
string? |
null |
折叠宽度(如 "60px") |
CollapsedRailMode |
SxAppShellCollapsedRailMode |
Auto |
窄条显示策略 |
AlwaysShowSidebar |
bool? |
null |
是否始终显示侧边栏(小屏幕也显示窄条) |
ShowContentNavBarWhenCollapsed |
bool |
true |
折叠时是否显示内容区导航栏 |
SizingMode |
SxAppShellSizingMode |
Viewport |
尺寸策略(Viewport/Container) |
LayoutMode |
SxAppShellLayoutMode? |
null |
布局模式(null=自动, Sidebar, Drawer) |
BreakpointConfig |
SxAppShellBreakpointConfig? |
null |
自定义断点配置 |
DrawerOverlayMode |
SxAppShellDrawerOverlayMode |
Transparent |
抽屉遮罩模式 |
EnableSafeArea |
bool |
true |
是否启用安全区(移动端) |
NavigationMode |
SxAppShellNavigationMode |
Auto |
导航模式 |
NavigationContent |
RenderFragment<string?>? |
null |
内部导航内容模板 |
RouteAppAssembly |
Assembly? |
null |
内部路由程序集 |
RouteAdditionalAssemblies |
IEnumerable<Assembly>? |
null |
额外路由程序集 |
RouteDefaultLayout |
Type? |
null |
默认布局类型 |
RouteFound |
RenderFragment<RouteData>? |
null |
路由匹配模板 |
RouteNotFound |
RenderFragment? |
null |
路由未匹配模板 |
InitialRoute |
string? |
null |
初始路由路径 |
SyncBrowserUrl |
bool |
true |
是否同步浏览器 URL |
MaxHistoryDepth |
int? |
null |
单 Tab 历史栈深度限制 |
MaxCachedPages |
int? |
null |
缓存页面数量限制 |
BottomBar |
RenderFragment? |
null |
底部栏内容(固定在侧边栏底部,可放置 SxUserBar 等组件) |
Events
| 事件名 | 类型 | 描述 |
|---|---|---|
BreakpointChanged |
EventCallback<Breakpoint> |
断点变化时触发 |
CollapsedChanged |
EventCallback<bool> |
折叠状态变化时触发 |
OnNavigate |
EventCallback<string?> |
内部导航时触发 |
OnBack |
EventCallback |
返回时触发 |
OnHome |
EventCallback |
返回首页时触发 |
Methods
| 方法名 | 返回值 | 描述 |
|---|---|---|
ToggleSidebar() |
void |
切换侧边栏折叠状态 |
OnBreakpointChanged(string) |
void |
JS 调用的断点变化回调 |
枚举类型
public enum Breakpoint { XS, SM, MD, LG, XL }
public enum SxAppShellSizingMode { Viewport, Container }
public enum SxAppShellLayoutMode { Auto, Sidebar, Drawer }
public enum SxAppShellCollapsedRailMode { Auto, Show, Hidden }
public enum SxAppShellDrawerOverlayMode { Transparent, Hidden }
public enum SxAppShellNavigationMode { Auto, Internal, External }
常见问题
Q: 点击折叠按钮无响应?
检查以下几点:
- ServerPrerendered 模式下是否提供了
Id参数 IUserPreferences和INavStackService服务是否已注册- 浏览器控制台是否有 JS 错误
Q: 断点变化不触发?
确保:
blazor.server.js或blazor.webassembly.js已正确加载- 组件已完成水合(预渲染模式)
BreakpointConfig配置正确
Q: 内部导航不工作?
检查:
NavigationMode是否正确设置NavigationContent或RouteAppAssembly是否提供SyncBrowserUrl设置是否符合预期