{ "schemaVersion": 1, "sourceKind": "authored-spec", "provenance": "authored-in-repo", "specFile": "spec/移动端规格.md", "specSection": "2 · 底部标签栏 TabBar", "confidence": "high", "slug": "tabbar", "name": "底部标签栏 TabBar", "semanticTypeCandidates": [ "tabbar", "bottom-navigation", "tablist" ], "variantDimensions": [ { "name": "count", "values": [ "2", "3", "4", "5" ] }, { "name": "badge", "values": [ "none", "dot", "number" ] } ], "representativeVariants": [ { "count": "3", "badge": "none", "label": "三项基础" }, { "count": "4", "badge": "number", "label": "四项 + 数字角标" }, { "count": "5", "badge": "dot", "label": "五项 + 红点" }, { "count": "4", "badge": "dot", "label": "含禁用项" } ], "anatomy": { "bar": "标签栏容器,固定于页面底部,高度 50px + 底部安全区", "item": "单个标签,含图标与文字", "icon": "图标,可为内联 SVG", "label": "标签文字,11px", "badge": "角标,可为数字或红点" }, "structurePatterns": { "count": "2 / 3 / 4 / 5(标签数量,超过 5 项应改用其它导航形态)", "badge": "none / dot / number" }, "usageHints": [ "底部主导航,2~5 个标签页之间切换,是移动端一级导航", "固定于页面底部,高度 50px + 底部安全区", "每项点击热区等分整栏宽度,高度不小于 44px", "选中项切换后 aria-selected 同步变化", "底部内边距包含安全区", "标签文字 11px,图标可为内联 SVG" ], "doNotInvent": [ "标签项超过 5 个时的滚动或折叠规则", "图标资源的成套规则(规格只约定尺寸与语义)" ], "unknowns": [ "角标超过两位数的收敛(如 99+)", "选中态是否带图标填充切换" ], "interaction": [ "每项点击热区等分整栏宽度,高度不小于 44px", "选中项切换后 aria-selected 同步变化", "底部内边距包含安全区" ], "accessibility": [ "容器 role=tablist,单项 role=tab", "选中项 aria-selected=true,未选中 false", "每项具备 aria-label(图标 + 文字时可用文字代替)" ], "api": { "source": "implementation", "note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs", "props": [ { "name": "items", "type": "Item[]", "default": "[]", "desc": "标签项:{ key, label, icon?, badge?, dot?, disabled?, ariaLabel? }(规格 §2.2)", "required": false }, { "name": "value", "type": "string", "default": "''", "desc": "当前选中项的 key(受控,规格 §2.4)", "required": false }, { "name": "label", "type": "string", "default": "'主导航'", "desc": "整栏的无障碍名称(role=tablist 的 aria-label,规格 §2.6)", "required": false } ], "events": [ { "name": "change", "params": "key: string", "desc": "切换标签时触发,参数为选中项的 key" } ], "slots": [ { "name": "—", "desc": "无插槽;项由 items 驱动(uni-app 端的图标由宿主以图片/slot 提供,规格 §2.7)" } ], "requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。" }, "variantClasses": { "count": { "2": [ "(.kole-m-tabbar__item)" ], "3": [ "(.kole-m-tabbar__item)" ], "4": [ "(.kole-m-tabbar__item)" ], "5": [ "(.kole-m-tabbar__item)" ] }, "badge": { "none": [], "dot": [ ".kole-m-tabbar__badge", ".is-dot" ], "number": [ ".kole-m-tabbar__badge" ] } }, "demos": [ { "id": "count-3", "group": "01 组件类型", "title": "三项", "desc": "最常见的三项导航:图标 + 文字等分整栏宽度,热区高度 ≥ 44px。", "variant": "count=3" }, { "id": "count-4-badge", "group": "01 组件类型", "title": "四项 + 数字角标", "desc": "角标宽度随位数增长;超过两位数按业务约定收敛(如 99+)。", "variant": "count=4 / badge=number" }, { "id": "count-5-dot", "group": "01 组件类型", "title": "五项 + 红点", "desc": "五项是上限,标签文字仍不换行;红点用于「有更新但不必计数」。", "variant": "count=5 / badge=dot" }, { "id": "disabled", "group": "02 组件状态", "title": "含禁用项", "desc": "禁用项置灰、保留位置、不参与切换(无权限模块的常见表达)。", "variant": "disabled" } ], "related": [ { "slug": "navbar", "why": "顶栏给标题与返回,标签栏给主模块切换;两者一起构成一级框架" }, { "slug": "pullrefresh", "why": "都在页面上做纵向处理,注意手势与底部导航栏不要抢事件" } ] }