ElTree Utils

2025-11-09 10:49:00

获取选中的树结构

getCheckedNodes.ts
test.ts
          type 
TreeNode
<
T
= any> =
T
& {
children
?:
Array
<
TreeNode
<
T
>> }
/** * 根据选中 keys 过滤树结构,只保留选中节点及其父级 * @param tree 完整树结构 * @param checkedKeys 已选中的节点 key 列表 * @param keyField 节点唯一键名 */ function
getCheckedNodes
<
T
>(
tree
:
Array
<
TreeNode
<
T
>>,
checkedKeys
:
Array
<string | number>,
keyField
: keyof T
):
Array
<
TreeNode
<
T
>> {
const
selectedSet
= new
Set
(
checkedKeys
)
function
filterNodes
(
nodes
:
TreeNode
[]):
TreeNode
[] {
return nodes .
map
(
node
=> {
const
children
=
node
.children ?
filterNodes
(
node
.children) : []
const
isSelected
=
selectedSet
.
has
(
node
[
keyField
])
// 如果当前节点被选中或有选中的子节点,则保留 if (
isSelected
||
children
.
length
> 0) {
return { ...
node
,
children
}
} return null }) .
filter
(
Boolean
)
} return
filterNodes
(
tree
)
}
          const origin = [
    {
        id: '1',
        children: [{ id: '1-1' }]
    },
    {
        id: '2',
        children: [{ id: '2-1' }, { id: '2-2' }]
    }
]

const tree = getCheckedNodes(origin, ['1', '1-1', '2-1'], 'id')
console.log(tree)
/**
[
  {
    id: "1",
    children: [{ id: "1-1" }],
  },
  {
    id: "2",
    children: [{ id: "2-1" }],
  },
];
*/

        

获取当前选中的树节点key

getCheckedKeys.ts
test.ts
          type 
TreeNode
<
T
= any> =
T
& {
children
?:
Array
<
TreeNode
<
T
>> }
/** * 根据完整树 fullTree 和部分树 targetTree 推算 checkedKeys(多层支持) * @param fullTree 完整树 * @param targetTree 当前树(可能只包含部分节点,但需要和fullTree结构、嵌套关系相同) * @param key 节点唯一键名 */ export function
getCheckedKeys
<
T
>(
fullTree
:
Array
<
TreeNode
<
T
>>,
targetTree
:
Array
<
TreeNode
<
T
>>,
key
: keyof T
): string[] { const
toKey
= (
n
:
T
) =>
String
(
n
[
key
])
// 记录 target 中显式出现的节点 key const
explicit
= new
Set
<string>()
const
explicitNoChildren
= new
Set
<string>()
const
dfsTarget
= (
n
:
TreeNode
<
T
>) => {
const
k
=
toKey
(
n
)
explicit
.
add
(
k
)
if (
n
.
children
?.
length
)
n
.
children
.
forEach
(
dfsTarget
)
else
explicitNoChildren
.
add
(
k
)
}
targetTree
.
forEach
(
dfsTarget
)
const
result
= new
Set
<string>()
/** 返回当前节点是否被选中 */ const
dfsFull
= (
n
:
TreeNode
<
T
>): boolean => {
const
k
=
toKey
(
n
)
if (!
n
.
children
?.
length
) {
if (
explicit
.
has
(
k
))
result
.
add
(
k
)
return
explicit
.
has
(
k
)
} const
allChildrenSelected
=
n
.
children
.
map
(
dfsFull
).
every
(
Boolean
)
const
parentExplicit
=
explicitNoChildren
.
has
(
k
)
if (
parentExplicit
||
allChildrenSelected
) {
result
.
add
(
k
)
n
.
children
.
forEach
(
c
=>
result
.
add
(
toKey
(
c
)))
return true } return false }
fullTree
.
forEach
(
dfsFull
)
return [...
result
]
}
          const origin = [
    {
        id: '1',
        children: [{ id: '1-1', children: [{ id: '1-1-1' }, { id: '1-1-2' }] }]
    },
    {
        id: '2',
        children: [{ id: '2-1' }, { id: '2-2' }]
    }
]

const target = [
    {
        id: '1',
        children: [{ id: '1-1', children: [{ id: '1-1-1' }, { id: '1-1-2' }] }]
    },
    {
        id: '2',
        children: [{ id: '2-1' }]
    }
]

const checkedKeys = getCheckedKeys(origin, target, "id");
console.log(checkedKeys)
// ["1", "1-1", "1-1-1", "1-1-2", "2-1"]

        
© 2021-2025 sunshj's Blog