LineTree 带线的树
使 ElTree 组件带有线的功能
基础用法
默认使用姿势与ElTree
一致。
Level one 1
Level one 2
Level one 3
vue
<template>
<el-line-tree
style="max-width: 600px"
:data="data"
@node-click="handleNodeClick"
/>
</template>
<script lang="ts" setup>
interface Tree {
label: string
children?: Tree[]
}
const handleNodeClick = (data: Tree) => {
console.log(data)
}
const data: Tree[] = [
{
label: 'Level one 1',
children: [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
children: [
{
label: 'Level four 1-1-1-1',
children: [
{
label: 'Level five 1-1-1-1-1',
},
],
},
{
label: 'Level four 1-1-1-1',
children: [
{
label: 'Level five 1-1-1-1-1',
},
],
},
],
},
],
},
{
label: 'Level two 1-2',
},
],
},
{
label: 'Level one 2',
children: [
{
label: 'Level two 2-1',
children: [
{
label: 'Level three 2-1-1',
},
],
},
{
label: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
},
],
},
],
},
{
label: 'Level one 3',
children: [
{
label: 'Level two 3-1',
children: [
{
label: 'Level three 3-1-1',
},
],
},
{
label: 'Level two 3-2',
children: [
{
label: 'Level three 3-2-1',
},
],
},
],
},
]
</script>
隐藏源代码
线的弧度
使用line-radius
属性来设置线的弧度。使用line-color
设置线的颜色。
使用icon
组件和icon-props
来快速设置折叠器的 icon 及属性
Level one 1
Level one 2
Level one 3
vue
<template>
<el-line-tree
style="max-width: 600px"
:data="data"
:show-checkbox="false"
line-radius="4px"
line-color="red"
:icon="Edit"
:icon-props="{ color: 'red' }"
@node-click="handleNodeClick"
/>
</template>
<script lang="ts" setup>
import { Edit } from '@element-plus/icons-vue'
interface Tree {
label: string
children?: Tree[]
}
const handleNodeClick = (data: Tree) => {
console.log(data)
}
const data: Tree[] = [
{
label: 'Level one 1',
children: [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
children: [
{
label: 'Level four 1-1-1-1',
children: [
{
label: 'Level five 1-1-1-1-1',
},
],
},
{
label: 'Level four 1-1-1-1',
children: [
{
label: 'Level five 1-1-1-1-1',
},
],
},
],
},
],
},
{
label: 'Level two 1-2',
},
],
},
{
label: 'Level one 2',
children: [
{
label: 'Level two 2-1',
children: [
{
label: 'Level three 2-1-1',
},
],
},
{
label: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
},
],
},
],
},
{
label: 'Level one 3',
children: [
{
label: 'Level two 3-1',
children: [
{
label: 'Level three 3-1-1',
},
],
},
{
label: 'Level two 3-2',
children: [
{
label: 'Level three 3-2-1',
},
],
},
],
},
]
</script>
隐藏源代码
自定义折叠器
使用collapse
插槽来设置自定义折叠器。当使用自定义折叠器插槽时,修改 ui 尺寸后,必须设置collapse-width
的值,该值为自定义折叠器UI
的宽度。
由于线的位置是基于自定义折叠器UI
的宽度动态通过 css 计算的,所以需要设置collapse-width
值,当然你也可以手动修改 css 变量也行,只不过没有该属性方便。
Level one 1
Level one 2
Level one 3
vue
<template>
<el-line-tree
style="max-width: 600px"
:data="options"
line-radius="4px"
collapse-width="14px"
@node-click="handleNodeClick"
>
<template #collapse="{ node }">
<el-icon
size="14"
:class="node.isLeaf ? 'is-leaf' : ''"
color="var(--el-tree-expand-icon-color)"
>
<component :is="node.expanded ? CaretBottom : CaretRight" />
</el-icon>
</template>
</el-line-tree>
</template>
<script lang="ts" setup>
import { CaretBottom, CaretRight } from '@element-plus/icons-vue'
interface Tree {
label: string
children?: Tree[]
}
const handleNodeClick = (data: Tree) => {
console.log(data)
}
const options: Tree[] = [
{
label: 'Level one 1',
children: [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
children: [
{
label: 'Level four 1-1-1-1',
children: [
{
label: 'Level five 1-1-1-1-1',
},
],
},
{
label: 'Level four 1-1-1-1',
children: [
{
label: 'Level five 1-1-1-1-1',
},
],
},
],
},
],
},
{
label: 'Level two 1-2',
},
],
},
{
label: 'Level one 2',
children: [
{
label: 'Level two 2-1',
children: [
{
label: 'Level three 2-1-1',
},
],
},
{
label: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
},
],
},
],
},
{
label: 'Level one 3',
children: [
{
label: 'Level two 3-1',
children: [
{
label: 'Level three 3-1-1',
},
],
},
{
label: 'Level two 3-2',
children: [
{
label: 'Level three 3-2-1',
},
],
},
],
},
]
</script>
隐藏源代码
自定义节点内容
使用默认插槽
可以自定义节点内容,由于业务的复杂性,节点的高度可能不是固定的,比如这面这个案列
当自定义节点的内容也需要连线时,可以使用show-content-line
属性开启
接收消息: 0s
工作流调用: 5s
开始: 0s
意图识别: 1s
输出: 0s
汇总响应: 0s
输出: 0s
vue
<template>
<el-line-tree
:data="options"
line-radius="4px"
collapse-width="20px"
default-expand-all
show-content-line
:expand-on-click-node="false"
style="max-width: 600px"
>
<template #collapse="{ data }">
<el-image
:src="data.img"
style="width: 20px; height: 20px; border-radius: 6px; z-index: 1"
/>
</template>
<template #default="{ data }">
<div class="line-tree__node-header">
<div>
{{ data.label }}: <span> {{ data.time }}s</span>
</div>
<el-icon
style="margin-left: 6px"
@click.stop="data.visible = !data.visible"
>
<component :is="data.visible ? CaretTop : CaretBottom" />
</el-icon>
</div>
<el-collapse-transition>
<div
v-if="data.visible"
style="height: 80px"
class="line-tree__node-content"
>
{{ data.content }}
</div>
</el-collapse-transition>
</template>
</el-line-tree>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { CaretBottom, CaretTop } from '@element-plus/icons-vue'
import type { Ref } from 'vue'
interface Tree {
label: string
children?: Tree[]
[prop: string]: any
}
const options: Ref<Tree[]> = ref([
{
label: '接收消息',
img: 'https://oss.real-bot.cn/web/om/workflow/receiving_message.png',
time: 0,
content: '接收消息-1',
visible: false,
},
{
label: '工作流调用',
time: 5,
img: 'https://oss.real-bot.cn/web/om/workflow/workflow_call.png',
content: '工作流调用-1',
visible: false,
children: [
{
label: '开始',
img: 'https://oss.real-bot.cn/web/om/workflow/logic-start.png',
time: 0,
content: '开始-1',
visible: false,
children: [
{
label: '意图识别',
img: 'https://oss.real-bot.cn/web/om/workflow/sop_intent_recognition.png',
time: 1,
content: '意图识别-1',
visible: false,
children: [
{
label: '输出',
img: 'https://oss.real-bot.cn/web/om/workflow/output.png',
time: 0,
content: '输出-1',
visible: false,
},
],
},
],
},
],
},
{
label: '汇总响应',
img: 'https://oss.real-bot.cn/web/om/workflow/response_summary.png',
time: 0,
content: '汇总响应-1',
visible: false,
children: [
{
label: '输出',
img: 'https://oss.real-bot.cn/web/om/workflow/output.png',
time: 0,
content: '输出-2',
visible: false,
},
],
},
])
</script>
<style lang="scss" scoped>
.line-tree__node-header {
display: flex;
align-items: center;
line-height: 20px;
margin: 6px;
}
.line-tree__node-content {
padding: 12px;
width: 100%;
margin: 12px 0;
border-radius: 6px;
cursor: auto;
background-color: var(--el-color-primary-light-9);
color: var(--el-text-color-primary);
}
</style>
隐藏源代码
原有功能
因为ElLineTree
本是通过css
修改而来,所以ElTree
的功能都保留
Root1
Root2
vue
<template>
<el-line-tree
style="max-width: 600px"
:props="props"
:load="loadNode"
lazy
show-checkbox
line-color="var(--el-border-color)"
:icon-props="{ color: 'var(--el-border-color)' }"
@check-change="handleCheckChange"
/>
</template>
<script lang="ts" setup>
interface Tree {
name: string
}
let count = 1
const props = {
label: 'name',
children: 'zones',
}
const handleCheckChange = (
data: Tree,
checked: boolean,
indeterminate: boolean
) => {
console.log(data, checked, indeterminate)
}
const loadNode = (node, resolve) => {
if (node.level === 0) {
return resolve([{ name: 'Root1' }, { name: 'Root2' }])
}
if (node.level > 3) return resolve([])
let hasChild = false
if (node.data.name === 'region1') {
hasChild = true
} else if (node.data.name === 'region2') {
hasChild = false
} else {
hasChild = Math.random() > 0.5
}
setTimeout(() => {
let data: Tree[] = []
if (hasChild) {
data = [
{
name: `zone${count++}`,
},
{
name: `zone${count++}`,
},
]
} else {
data = []
}
resolve(data)
}, 500)
}
</script>
隐藏源代码
API
属性
其他相关的 API 属性,请参考 ElTree 即可,剩下是 LineTree
组件独有的 API 属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
line-radius | 线的弧度 | String | 0px |
line-color | 线的颜色 | String | - |
collapse-width | 当自定义 collapse 内容时,需要设置 collapse 的宽度值,为了调整连线的位置 | String | 15px |
show-content-line | 自定义 content 后,子内容的高度可能变化,添加一条线会更好 | Boolean | false |
icon-props | 自定义图标的属性 | Object | - |
Slots
事件名 | 说明 |
---|---|
collapse | 自定义折叠器 |
default | 自定义节点内容 |