106 lines
6.3 KiB
JSON
106 lines
6.3 KiB
JSON
{
|
||
"slug": "treetable",
|
||
"end": "vue3",
|
||
"curated": true,
|
||
"summary": "Vue 3 树形表格:columns 配嵌套 data,展开行按 leafSum 汇总数字列,选中态以 v-model:selectedKeys 回吐。",
|
||
"usage": [
|
||
"data 是嵌套结构,每行取 rowKey 作主键(默认 'key');展开后 visibleList 递归出 { node, depth } 扁平列表供渲染(frameworks/TreeTable.vue3.vue:14,57-58,87-95)。",
|
||
"只有第一列画树:col.key === columns[0].key 的那格才渲染 .tree-cell 与展开箭头,其余列走 cellValue 直取字段(frameworks/TreeTable.vue3.vue:25-35)。",
|
||
"选中走 v-model:selected-keys:selectedKeys prop 配 update:selectedKeys 事件,行点击是单选覆盖、复选框是级联勾选(frameworks/TreeTable.vue3.vue:60,65,107-118)。",
|
||
"复选框勾选会连带整棵子树:toggleCheck 先算 descendantKeys 一起增删,再 propagate 自底向上补父节点的选中态(frameworks/TreeTable.vue3.vue:108-119)。",
|
||
"表头全选只针对叶子:allSelected 用 leafKeys() 逐个比对,父节点不在比对范围内,避免行数口径被父行污染(frameworks/TreeTable.vue3.vue:77-82,96)。",
|
||
"汇总列是 summaryColumn 指定的单个字段:父行在该列显示 leafSum 的子树合计,tfoot 里再用 totalOf 汇总全表(frameworks/TreeTable.vue3.vue:33,101-104)。",
|
||
"汇总行的显示条件是 summaryColumn 非空(showSummary 计算属性),summary.label 只提供左侧文字,默认 '合计'(frameworks/TreeTable.vue3.vue:39-46,86)。"
|
||
],
|
||
"bestPractices": [
|
||
"summaryColumn 只支持一列:想同时汇总人数与预算得拆成两个表或用 SummaryRowTable,tfoot 里其余列固定渲染空串(frameworks/TreeTable.vue3.vue:43-45)。",
|
||
"cellValue 对含子节点的行在 summaryColumn 上返回 leafSum,所以数据里父行的该字段值会被忽略、以叶子合计为准(frameworks/TreeTable.vue3.vue:102-105)。",
|
||
"leafSum 用 Number(node[key]) || 0 对叶子取值,缺字段或非数字一律按 0 累加,不会算出 NaN(frameworks/TreeTable.vue3.vue:73-76)。",
|
||
"展开态同 Tree 一样默认由 defaultExpandedKeys 预置且不受控;selectedKeys 也只作初值,内部另有 Set 维护(frameworks/TreeTable.vue3.vue:67-70)。",
|
||
"父行同时带 (汇总) 标记(tt-summary)才说明它是汇总值,这个 span 要求 hasChildren(row.node) 且 summaryColumn 非空(frameworks/TreeTable.vue3.vue:33)。",
|
||
"行点击与复选框点击要分开:复选框用 @click.stop 阻止冒泡,否则点勾选会顺带把该行切成单选选中(frameworks/TreeTable.vue3.vue:16,19)。"
|
||
],
|
||
"a11y": [
|
||
"骨架是原生 <table> 配 thead/tbody/tfoot,行列语义完整,但表头 <th> 没有 scope=\"col\"(frameworks/TreeTable.vue3.vue:3-9)。",
|
||
"展开箭头是 <span>▸</span>,靠 is-open 旋转 90°,无 aria-expanded、无 tabindex,键盘无法展开(frameworks/TreeTable.vue3.vue:26-31)。",
|
||
"全选与行选择都是原生 <input type=\"checkbox\">,三态用 :indeterminate.prop,但都没有 label 关联,读屏器只有「复选框」一个名字(frameworks/TreeTable.vue3.vue:7,19)。",
|
||
"数据行是带 @click 的 <tr>,不可聚焦也不响应键盘,选中操作对键盘用户不可达(frameworks/TreeTable.vue3.vue:13-16)。"
|
||
],
|
||
"apiCarrier": {
|
||
"kind": "props",
|
||
"note": "Vue 3 端载体是 8 个 props(columns 与 data 必填,另有 rowKey / selectable / selectedKeys / defaultExpandedKeys / summaryColumn / summary)与 2 个 emit(update:selectedKeys / row-click);无插槽。",
|
||
"table": [
|
||
{
|
||
"name": "columns",
|
||
"type": "Array",
|
||
"desc": "列配置(frameworks/TreeTable.vue3.vue:9)"
|
||
},
|
||
{
|
||
"name": "data",
|
||
"type": "属性",
|
||
"desc": "必填的树形行数据(子节点放 children),经 visibleList 递归成扁平行(frameworks/TreeTable.vue3.vue:57,87-95)"
|
||
},
|
||
{
|
||
"name": "defaultExpandedKeys",
|
||
"type": "Array",
|
||
"desc": "默认展开项(frameworks/TreeTable.vue3.vue:61)"
|
||
},
|
||
{
|
||
"name": "rowKey",
|
||
"type": "属性",
|
||
"desc": "行唯一键字段名(默认 key),用于 :key 与选中/展开判定(frameworks/TreeTable.vue3.vue:14,58)"
|
||
},
|
||
{
|
||
"name": "selectable",
|
||
"type": "Boolean",
|
||
"desc": "是否可选择(frameworks/TreeTable.vue3.vue:6)"
|
||
},
|
||
{
|
||
"name": "selectedKeys",
|
||
"type": "Array",
|
||
"desc": "已选中项(frameworks/TreeTable.vue3.vue:60)"
|
||
},
|
||
{
|
||
"name": "summary",
|
||
"type": "Object",
|
||
"desc": "汇总配置(frameworks/TreeTable.vue3.vue:33)"
|
||
},
|
||
{
|
||
"name": "summaryColumn",
|
||
"type": "String",
|
||
"desc": "汇总列(frameworks/TreeTable.vue3.vue:33)"
|
||
},
|
||
{
|
||
"name": "row-click",
|
||
"type": "(val: any) => void",
|
||
"desc": "点击数据行时触发(frameworks/TreeTable.vue3.vue:65)"
|
||
}
|
||
]
|
||
},
|
||
"resources": [
|
||
{
|
||
"file": "frameworks/TreeTable.vue3.vue",
|
||
"kind": "Vue 3",
|
||
"desc": "该端实现(本页 API 与用法的唯一权威来源)。"
|
||
},
|
||
{
|
||
"file": "frameworks/TreeTable.css",
|
||
"kind": "样式",
|
||
"desc": "该组件的样式文件,类名口径以它为准。"
|
||
}
|
||
],
|
||
"exampleIds": [
|
||
"treetable-ex-1"
|
||
],
|
||
"notes": [
|
||
"依据 frameworks/TreeTable.vue3.vue:55-64 defineProps 八项,columns 与 data 均 required,rowKey 默认 'key'。",
|
||
"依据 frameworks/TreeTable.vue3.vue:65 defineEmits(['update:selectedKeys','row-click']),派发点见 107 与 118 行。",
|
||
"依据 frameworks/TreeTable.vue3.vue:87-95 visibleList 递归出 depth;25 行缩进写法为 row.depth * 16。",
|
||
"依据 frameworks/TreeTable.vue3.vue:73-82 leafSum / leafKeys 的叶子口径,96-97 行 allSelected 与 someSelected 只用叶子。",
|
||
"依据 frameworks/TreeTable.vue3.vue:86 showSummary 与 39-46 行 tfoot 只填 summaryColumn 对应的列。",
|
||
"依据 frameworks/TreeTable.vue3.vue:67-70 内部 Set 维护 expanded / selected,props 仅作初值。",
|
||
"依据 frameworks/TreeTable.vue3.vue:33 .tt-summary 父行汇总标记的渲染条件。",
|
||
"契约声明的驱动维度(feature / level)属设计词汇层,未作为 prop 写入本页。"
|
||
]
|
||
}
|