FxSelectTree 树形选择器
FxSelectTree 属于 @fx/components,组合
FxSelect+FxTree:下拉面板内渲染一棵树,选中节点同步为选择器的值。
下拉菜单中的树形选择器,结合了 FxTree 与 FxSelect 的能力。
基础用法
树形结构的选择器。
vue
<template>
<FxSelectTree
v-model="value"
:data="data"
:render-after-expand="false"
style="width: 240px"
/>
<FxDivider />
show checkbox:
<FxSelectTree
v-model="value"
:data="data"
:render-after-expand="false"
show-checkbox
style="width: 240px"
/>
</template>
<script lang="ts" setup>
import { ref } from "vue"
const value = ref()
const data = [
{
value: "1",
label: "一级 1",
children: [
{
value: "1-1",
label: "二级 1-1",
children: [{ value: "1-1-1", label: "三级 1-1-1" }],
},
],
},
{
value: "2",
label: "一级 2",
children: [
{
value: "2-1",
label: "二级 2-1",
children: [{ value: "2-1-1", label: "三级 2-1-1" }],
},
{
value: "2-2",
label: "二级 2-2",
children: [{ value: "2-2-1", label: "三级 2-2-1" }],
},
],
},
{
value: "3",
label: "一级 3",
children: [
{
value: "3-1",
label: "二级 3-1",
children: [{ value: "3-1-1", label: "三级 3-1-1" }],
},
{
value: "3-2",
label: "二级 3-2",
children: [{ value: "3-2-1", label: "三级 3-2-1" }],
},
],
},
]
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
选择任意层级
使用 check-strictly 时可选择任意层级节点,否则只能选择叶子节点。
TIP
使用 show-checkbox 时,由于 check-on-click-node 默认为 false,只能通过勾选选择;如需点击节点即选中,可将其设为 true。
vue
<template>
<FxSelectTree
v-model="value"
:data="data"
check-strictly
:render-after-expand="false"
style="width: 240px"
/>
<FxDivider />
show checkbox:
<FxSelectTree
v-model="value"
:data="data"
check-strictly
:render-after-expand="false"
show-checkbox
style="width: 240px"
/>
<FxDivider />
show checkbox with <code>check-on-click-node</code>:
<FxSelectTree
v-model="value"
:data="data"
check-strictly
:render-after-expand="false"
show-checkbox
check-on-click-node
style="width: 240px"
/>
</template>
<script lang="ts" setup>
import { ref } from "vue"
const value = ref()
const data = [
{
value: "1",
label: "一级 1",
children: [
{
value: "1-1",
label: "二级 1-1",
children: [{ value: "1-1-1", label: "三级 1-1-1" }],
},
],
},
{
value: "2",
label: "一级 2",
children: [
{
value: "2-1",
label: "二级 2-1",
children: [{ value: "2-1-1", label: "三级 2-1-1" }],
},
{
value: "2-2",
label: "二级 2-2",
children: [{ value: "2-2-1", label: "三级 2-2-1" }],
},
],
},
{
value: "3",
label: "一级 3",
children: [
{
value: "3-1",
label: "二级 3-1",
children: [{ value: "3-1-1", label: "三级 3-1-1" }],
},
{
value: "3-2",
label: "二级 3-2",
children: [{ value: "3-2-1", label: "三级 3-2-1" }],
},
],
},
]
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
WARNING
使用 show-checkbox 时,由于 check-on-click-leaf 默认为 true,点击叶子节点(最末级)会同时切换其勾选状态。
多选
通过点击或 checkbox 进行多选。
vue
<template>
<FxSelectTree
v-model="value"
:data="data"
multiple
:render-after-expand="false"
style="width: 240px"
/>
<FxDivider />
show checkbox:
<FxSelectTree
v-model="value"
:data="data"
multiple
:render-after-expand="false"
show-checkbox
style="width: 240px"
/>
<FxDivider />
show checkbox with <code>check-strictly</code>:
<FxSelectTree
v-model="valueStrictly"
:data="data"
multiple
:render-after-expand="false"
show-checkbox
check-strictly
check-on-click-node
style="width: 240px"
/>
</template>
<script lang="ts" setup>
import { ref } from "vue"
const value = ref()
const valueStrictly = ref()
const data = [
{
value: "1",
label: "一级 1",
children: [
{
value: "1-1",
label: "二级 1-1",
children: [{ value: "1-1-1", label: "三级 1-1-1" }],
},
],
},
{
value: "2",
label: "一级 2",
children: [
{
value: "2-1",
label: "二级 2-1",
children: [{ value: "2-1-1", label: "三级 2-1-1" }],
},
{
value: "2-2",
label: "二级 2-2",
children: [{ value: "2-2-1", label: "三级 2-2-1" }],
},
],
},
{
value: "3",
label: "一级 3",
children: [
{
value: "3-1",
label: "二级 3-1",
children: [{ value: "3-1-1", label: "三级 3-1-1" }],
},
{
value: "3-2",
label: "二级 3-2",
children: [{ value: "3-2-1", label: "三级 3-2-1" }],
},
],
},
]
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
禁用
通过 disabled 字段禁用节点。
vue
<template>
<FxSelectTree v-model="value" :data="data" style="width: 240px" />
</template>
<script lang="ts" setup>
import { ref } from "vue"
const value = ref()
const data = [
{
value: "1",
label: "一级 1",
disabled: true,
children: [
{
value: "1-1",
label: "二级 1-1",
disabled: true,
children: [{ value: "1-1-1", label: "三级 1-1-1", disabled: true }],
},
],
},
{
value: "2",
label: "一级 2",
children: [
{
value: "2-1",
label: "二级 2-1",
children: [{ value: "2-1-1", label: "三级 2-1-1" }],
},
{
value: "2-2",
label: "二级 2-2",
children: [{ value: "2-2-1", label: "三级 2-2-1" }],
},
],
},
{
value: "3",
label: "一级 3",
children: [
{
value: "3-1",
label: "二级 3-1",
children: [{ value: "3-1-1", label: "三级 3-1-1" }],
},
{
value: "3-2",
label: "二级 3-2",
children: [{ value: "3-2-1", label: "三级 3-2-1" }],
},
],
},
]
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
可过滤
使用关键字过滤或自定义过滤方法。filter-method 自定义数据过滤;filter-node-method 自定义节点过滤。
vue
<template>
<FxSelectTree v-model="value" :data="data" filterable style="width: 240px" />
<FxDivider />
filter method:
<FxSelectTree
v-model="value"
:data="data"
:filter-method="filterMethod"
filterable
style="width: 240px"
/>
<FxDivider />
filter node method:
<FxSelectTree
v-model="value"
:data="data"
:filter-node-method="filterNodeMethod"
filterable
style="width: 240px"
/>
</template>
<script lang="ts" setup>
import { ref } from "vue"
interface Tree {
value: string
label: string
children?: Tree[]
}
const value = ref()
const sourceData: Tree[] = [
{
value: "1",
label: "一级 1",
children: [
{
value: "1-1",
label: "二级 1-1",
children: [{ value: "1-1-1", label: "三级 1-1-1" }],
},
],
},
{
value: "2",
label: "一级 2",
children: [
{
value: "2-1",
label: "二级 2-1",
children: [{ value: "2-1-1", label: "三级 2-1-1" }],
},
{
value: "2-2",
label: "二级 2-2",
children: [{ value: "2-2-1", label: "三级 2-2-1" }],
},
],
},
{
value: "3",
label: "一级 3",
children: [
{
value: "3-1",
label: "二级 3-1",
children: [{ value: "3-1-1", label: "三级 3-1-1" }],
},
{
value: "3-2",
label: "二级 3-2",
children: [{ value: "3-2-1", label: "三级 3-2-1" }],
},
],
},
]
const data = ref<Tree[]>(sourceData)
const filterMethod = (query: string) => {
data.value = [...sourceData].filter((item) => item.label.includes(query))
}
const filterNodeMethod = (query: string, node: Tree) =>
node.label.includes(query)
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
自定义节点内容
自定义树节点的内容。
vue
<template>
<FxSelectTree v-model="value" :data="data" style="width: 240px">
<template #default="{ data: nodeData }">
{{ nodeData.label }}<span style="color: gray">(suffix)</span>
</template>
</FxSelectTree>
<FxDivider />
使用 render-content:
<FxSelectTree
v-model="value"
:data="data"
:render-content="renderContent"
style="width: 240px"
/>
</template>
<script lang="ts" setup>
import { h, ref } from "vue"
import type { VNode } from "vue"
interface Tree {
value: string
label: string
children?: Tree[]
}
const value = ref()
const renderContent = (_h: typeof h, { data }: { data: Tree }): VNode => {
return h(
"span",
{
style: {
color: "#626AEF",
},
},
data.label,
)
}
const data: Tree[] = [
{
value: "1",
label: "一级 1",
children: [
{
value: "1-1",
label: "二级 1-1",
children: [{ value: "1-1-1", label: "三级 1-1-1" }],
},
],
},
{
value: "2",
label: "一级 2",
children: [
{
value: "2-1",
label: "二级 2-1",
children: [{ value: "2-1-1", label: "三级 2-1-1" }],
},
{
value: "2-2",
label: "二级 2-2",
children: [{ value: "2-2-1", label: "三级 2-2-1" }],
},
],
},
{
value: "3",
label: "一级 3",
children: [
{
value: "3-1",
label: "二级 3-1",
children: [{ value: "3-1-1", label: "三级 3-1-1" }],
},
{
value: "3-2",
label: "二级 3-2",
children: [{ value: "3-2-1", label: "三级 3-2-1" }],
},
],
},
]
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
懒加载
树节点懒加载,适合大数据量列表。
vue
<template>
<FxSelectTree
v-model="value"
lazy
:load="load"
:props="props"
style="width: 240px"
/>
<FxDivider />
配合 <code>cache-data</code> 显示懒加载节点 label:
<FxSelectTree
v-model="value2"
lazy
:load="load"
:props="props"
:cache-data="cacheData"
style="width: 240px"
/>
</template>
<script lang="ts" setup>
import { ref } from "vue"
interface LazyNode {
value: number
label: string
isLeaf?: boolean
}
const value = ref()
const value2 = ref(5)
const cacheData: LazyNode[] = [{ value: 5, label: "lazy load node5" }]
const props = {
label: "label",
children: "children",
isLeaf: "isLeaf",
}
let id = 0
const load = (
node: { isLeaf?: boolean },
resolve: (children: LazyNode[]) => void,
) => {
if (node.isLeaf) return resolve([])
setTimeout(() => {
resolve([
{ value: ++id, label: `lazy load node${id}` },
{ value: ++id, label: `lazy load node${id}`, isLeaf: true },
])
}, 400)
}
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
使用 node-key
默认 modelValue 查找 value 字段;数据结构不同时需提供 node-key 才能正常工作。
TIP
node-key应全树唯一。value-key与node-key作用相同。- 与 FxSelect 不同,FxSelectTree 不支持取对象值。
vue
<template>
<FxSelectTree
v-model="value"
style="width: 240px"
:data="data"
node-key="id"
show-checkbox
multiple
default-expand-all
/>
</template>
<script lang="ts" setup>
import { ref } from "vue"
interface Tree {
id: number
label: string
children?: Tree[]
}
const value = ref([2])
const data: Tree[] = [
{
id: 1,
label: "一级 1",
children: [
{ id: 2, label: "二级 1-1" },
{ id: 3, label: "二级 1-2" },
],
},
]
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
API
FxSelectTree 组合了 FxTree 与 FxSelect 的能力,原属性不再重复,请前往对应组件查阅:
| 维度 | tree | select |
|---|---|---|
| Attributes | FxTree Attributes | FxSelect Attributes |
| Events | FxTree Events | FxSelect Events |
| Slots | FxTree Slots | FxSelect Slots |
| Exposes | FxTree Exposes | FxSelect Exposes |
自有 Attributes
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| cache-data | 懒加载节点的缓存数据,结构同 data(含 value / label 等),用于获取未加载节点的 label | TreeNodeData[] | [] |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| treeRef | FxTree 实例 | FxTreeInstance |
| selectRef | FxSelect 实例 | FxSelectInstance |
| filter | 过滤所有树节点 | (value: unknown) => void |
| getCheckedKeys | 返回当前勾选的节点 key 数组 | (leafOnly?: boolean) => TreeKey[] |
| getCheckedNodes | 返回当前勾选的节点数据数组 | (leafOnly?: boolean, includeHalfChecked?: boolean) => TreeNodeData[] |
| setCheckedKeys | 勾选指定 key | (keys: TreeKey[]) => void |
| getHalfCheckedKeys | 返回半选节点 key 数组 | () => TreeKey[] |
| getHalfCheckedNodes | 返回半选节点数据数组 | () => TreeNodeData[] |
| getCurrentKey | 返回当前高亮节点的 key | () => TreeKey | null |
| getCurrentNode | 返回当前高亮节点的数据 | () => TreeNodeData | null |
| setCurrentKey | 设置高亮节点 | (key: TreeKey | null) => void |
| getNode | 按 data 或 key 获取节点 | (data: TreeKey | TreeNodeData) => unknown |
| focus | 聚焦输入框 | () => void |
| blur | 失焦并收起下拉 | () => void |
| selectedLabel | 当前选中标签 | ComputedRef<string> |
局部引入
ts
import { FxSelectTree } from "@fx/components"1
