73 lines
4.6 KiB
JSON
73 lines
4.6 KiB
JSON
{
|
||
"slug": "topmenu",
|
||
"end": "vue3",
|
||
"curated": true,
|
||
"summary": "Vue 3 顶栏菜单:items 树配 v-model:activeKey 记选中项,有子项的条目点击只展开、不派发选中。",
|
||
"usage": [
|
||
"选中值走具名 v-model:activeKey prop 配 update:activeKey 事件,同时还会派发 change 传同样的 key;示例里用 :active-key + @change 也成立(frameworks/TopMenu.vue3.vue:61,63,104-106)。",
|
||
"点有 children 的条目不会选中:select 里检测到 hasKids 就只切换 open 的展开态并 return,只有叶子节点的 key 才会写回 active(frameworks/TopMenu.vue3.vue:97-107)。",
|
||
"active 是内部 ref 且用 props.activeKey 做初值:之后父级改 activeKey 不会同步进组件,要用 v-model 回写驱动(frameworks/TopMenu.vue3.vue:66)。",
|
||
"父级高亮由 isTopActive 算:自身 key 命中或任一子项 key 命中都算激活,所以选了子项后父条目同时高亮(frameworks/TopMenu.vue3.vue:77-80)。",
|
||
"items 每项支持 key / label / icon / badge / disabled / children 六类字段,icon 与 badge 有值才渲染对应 span(frameworks/TopMenu.vue3.vue:6-8)。"
|
||
],
|
||
"bestPractices": [
|
||
"disabled 条目在 select 开头直接 return,点击既不展开也不派发事件;样式上同时给 is-disabled 与 not-allowed 光标(frameworks/TopMenu.vue3.vue:98 及 TopMenu.css:32-33)。",
|
||
"这是族生成实现:文件头标明 direction=top 由 gen-family-impl.mjs 生成,改行为要改族模板而不是这个文件(frameworks/TopMenu.vue3.vue:47-57)。",
|
||
"根节点写死 data-direction=\"top\",对应样式里的 .kole-menu[data-direction=\"top\"] 规则;同一份实现换参数即成为侧边菜单(frameworks/TopMenu.vue3.vue:2,56)。",
|
||
"collapsed 与 popItem 在当前参数下是死分支:collapsed 固为 false、popItem 要求 direction==='side',顶栏不会出现折叠浮层(frameworks/TopMenu.vue3.vue:68,85-88)。"
|
||
],
|
||
"a11y": [
|
||
"根节点是原生 <nav aria-label=\"主菜单\">,并给每个条目 role=\"menuitem\" 与 tabindex=\"0\",语义与键盘焦点基本到位(frameworks/TopMenu.vue3.vue:2-5)。",
|
||
"只有带子项的条目带 aria-expanded,且值取 String(open === it.key);叶子条目不输出该属性,属性口径是对的(frameworks/TopMenu.vue3.vue:21)。",
|
||
"条目只有 @click,没有键盘事件处理,聚焦到 menuitem 后按 Enter / 空格不会触发 select,键盘可用性不完整(frameworks/TopMenu.vue3.vue:5,22)。",
|
||
"role=\"menuitem\" 已隐含 aria-current 之外的选中语义缺失:当前激活项没有任何 aria-selected 或 aria-current 输出(frameworks/TopMenu.vue3.vue:4-5)。"
|
||
],
|
||
"apiCarrier": {
|
||
"kind": "props",
|
||
"note": "Vue 3 端载体是 2 个 props(items / activeKey)、2 个 emit(update:activeKey / change)与无插槽;菜单树通过 items 数据递归字段 children 表达。",
|
||
"table": [
|
||
{
|
||
"name": "activeKey",
|
||
"type": "String",
|
||
"desc": "当前激活项(frameworks/TopMenu.vue3.vue:61)"
|
||
},
|
||
{
|
||
"name": "items",
|
||
"type": "Array",
|
||
"desc": "数据项(frameworks/TopMenu.vue3.vue:4)"
|
||
},
|
||
{
|
||
"name": "change",
|
||
"type": "(val: any) => void",
|
||
"desc": "值变化时触发(frameworks/TopMenu.vue3.vue:63)"
|
||
}
|
||
]
|
||
},
|
||
"resources": [
|
||
{
|
||
"file": "frameworks/TopMenu.vue3.vue",
|
||
"kind": "Vue 3",
|
||
"desc": "该端实现(本页 API 与用法的唯一权威来源)。"
|
||
},
|
||
{
|
||
"file": "frameworks/TopMenu.css",
|
||
"kind": "样式",
|
||
"desc": "该组件的样式文件,类名口径以它为准。"
|
||
}
|
||
],
|
||
"exampleIds": [
|
||
"topmenu-ex-1",
|
||
"topmenu-ex-2",
|
||
"topmenu-ex-3"
|
||
],
|
||
"notes": [
|
||
"依据 frameworks/TopMenu.vue3.vue:59-62 defineProps 声明 items 与 activeKey;63 行 defineEmits(['update:activeKey','change'])。",
|
||
"依据 frameworks/TopMenu.vue3.vue:97-107 select 中 hasKids 分支只展开不派发,叶子才 emit 两事件。",
|
||
"依据 frameworks/TopMenu.vue3.vue:66 active 用 ref(props.activeKey) 初始化,非 computed,父级后续变更不回灌。",
|
||
"依据 frameworks/TopMenu.vue3.vue:2 根节点 data-direction 与 aria-label、4-5/13-14/20-22 行 role=\"menuitem\" 与 tabindex。",
|
||
"依据 frameworks/TopMenu.vue3.vue:21 aria-expanded 只在 hasKids 时输出。",
|
||
"依据 frameworks/TopMenu.vue3.vue:47-57 文件头注释声明这是 gen-family-impl.mjs 的生成物,族参数 direction=top。",
|
||
"契约声明的驱动维度(state / feature)属设计词汇层,未作为 prop 写入本页。"
|
||
]
|
||
}
|