导航 · 17 / 21
Navigation st-nav-bar
三个组件分工明确:st-nav-bar 控制排列方向,st-nav-item 控制文字位置与选中态,st-nav-layout 按自身宽度在底部导航、横排导航与左侧 rail 之间切换。active 始终由外部切换。
底部导航:icon 上、文字下
默认形态是 M3 底部导航栏:药丸高亮落在 icon 区域,文字在下方。用 attr:active 绑定当前索引,on:click 改 data;药丸背景会自动动画跟随。角标不是内置 API,用 icon 插槽里的原生绝对定位即可。
st-nav-bar + st-nav-item示例代码(含角标)
<st-nav-bar>
<st-nav-item attr:active="nav === 0" on:click="nav = 0">
<iconify-icon slot="icon" icon="mdi:home-outline"></iconify-icon>首页
</st-nav-item>
<st-nav-item attr:active="nav === 1" on:click="nav = 1">
<span slot="icon" style="position: relative;">
<iconify-icon icon="mdi:bell-outline"></iconify-icon><span style="position: absolute; top: -4px; right: -8px;">3</span>
</span>消息
</st-nav-item>
</st-nav-bar>
尺寸与外观:改 font-size 而非加变量
item 的 padding、药丸、图标与文字全部用 em 定义。缩放整条导航只需改 st-nav-bar 的 font-size;底色默认 surface-container,直接覆写 background、border-radius 即可,不需要额外属性。
font-size / background示例代码(缩放与换底色)
<st-nav-bar style="font-size: 12px; border-radius: 16px; overflow: hidden;">
<st-nav-item active><iconify-icon slot="icon" icon="mdi:inbox-arrow-down"></iconify-icon>收件箱</st-nav-item>
<st-nav-item><span slot="icon">🏷️</span>标签</st-nav-item>
</st-nav-bar>
纵向 rail 与抽屉
形态属性分两层:st-nav-bar 的 vertical 让子项纵向排列;st-nav-item 的 parallel 让文字移到 icon 右侧(active 药丸覆盖整行)。两者自由组合:vertical 得到窄 rail,vertical + parallel 得到抽屉。
vertical / parallel示例代码
<!-- 窄 rail:icon 上 / 文字下 -->
<st-nav-bar vertical style="position: fixed; left: 0; top: 0; bottom: 0;">
<st-nav-item active><iconify-icon slot="icon" icon="mdi:inbox-arrow-down"></iconify-icon>收件箱</st-nav-item>
<st-nav-item><span slot="icon">🏷️</span>标签</st-nav-item>
</st-nav-bar>
<!-- 抽屉:item 加 parallel,文字移到右边 -->
<st-nav-item parallel>...</st-nav-item>
禁用项 disabled
disabled 项透明度 0.38,内部原生 button 被禁用:点击、键盘与事件全部阻断,不会因点击变成当前项。active 仍由你的数据决定,请不要把禁用项设为当前项。
disabled示例代码
<st-nav-item disabled>
<iconify-icon slot="icon" icon="mdi:cog"></iconify-icon>设置
</st-nav-item>
响应式布局 st-nav-layout
st-nav-layout 按自身宽度(container query,不是视口)切换三档:小于 768px 底部导航;768–1023px 仍在底部但 item 自动横排;1024px 及以上移到左侧窄 rail。它自己给 bar 和 item 补 vertical / parallel,使用方不用手写断点。
st-nav-layout示例代码
<st-nav-layout style="height: 100vh;">
<st-nav-bar slot="nav">
<st-nav-item active><iconify-icon slot="icon" icon="mdi:home-outline"></iconify-icon>首页</st-nav-item>
<st-nav-item><iconify-icon slot="icon" icon="mdi:magnify"></iconify-icon>发现</st-nav-item>
</st-nav-bar>
<main>内容区(默认插槽,自动 overflow: auto)</main>
</st-nav-layout>
应用外壳:固定底部导航
真实应用里把导航固定在底部,内容区预留同样高度。st-nav-bar 可以 absolute / fixed 定位;st-nav-layout 只是布局容器,垂直排列时同样可以固定在视口边缘(记得给内容 padding-bottom)。
app shell示例代码(固定底部)
<main style="padding-bottom: 84px;">页面内容</main>
<st-nav-bar style="position: fixed; left: 0; right: 0; bottom: 0;">
<st-nav-item active><iconify-icon slot="icon" icon="mdi:home-outline"></iconify-icon>首页</st-nav-item>
<st-nav-item><span slot="icon">👤</span>我的</st-nav-item>
</st-nav-bar>
属性
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
vertical | boolean | 无 | st-nav-bar:子项纵向排列(rail / 抽屉) |
active | boolean | 无 | st-nav-item:当前项,药丸背景跟随 |
parallel | boolean | 无 | st-nav-item:文字在 icon 右侧,active 覆盖整行 |
disabled | boolean | 无 | st-nav-item:0.38 透明度,阻断点击与键盘 |
style | 原生 CSS | 无 | 用 font-size 缩放;background 等直接覆写 |
插槽 / 事件 / 注意
- st-nav-item 插槽:
icon/ 默认文字;st-nav-layout 插槽:nav/ 默认内容区。 - 事件:item 的 click 原生冒泡(composed);disabled 项不派发。
- 键盘:Tab 聚焦、Enter / Space 激活;focus-visible 有焦点环。
- 形态分两层:
vertical写 bar,parallel写 item,不要写错。 - st-nav-layout 断点:
<768px底部 /768–1023px底部横排 /≥1024px左侧 rail;按容器自身宽度判断。 - st-nav-layout 的高度依赖外部给定(如
height: 100vh),height: 100%无父高时为空。 - st-nav-layout 建议只放一个 st-nav-bar;bar 的底色可在宿主上覆盖。