自定义节点
组织节点通常需要展示名称、负责人、人数、状态等业务信息。Vue 渲染层通过 scoped slot 把布局结果交给业务组件。
节点组件
vue
<script setup lang="ts">
import type { PositionedNode } from '@org-tree/core'
defineProps<{
node: PositionedNode
selected?: boolean
}>()
defineEmits<{
select: [node: PositionedNode]
}>()
</script>
<template>
<button
class="org-node"
:class="{ 'org-node--selected': selected }"
:style="{
width: `${node.width}px`,
height: `${node.height}px`,
}"
type="button"
@click="$emit('select', node)"
>
<span class="org-node__name">{{ node.info.name }}</span>
<span class="org-node__owner">负责人:{{ node.info.owner ?? '未设置' }}</span>
<span class="org-node__count">{{ node.info.headcount ?? 0 }} 人</span>
</button>
</template>
<style scoped>
.org-node {
box-sizing: border-box;
display: grid;
grid-template-columns: 1fr auto;
gap: 6px 12px;
padding: 14px 16px;
color: #202124;
text-align: left;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 12px;
box-shadow: 0 8px 22px rgb(24 32 56 / 8%);
cursor: pointer;
}
.org-node--selected {
color: #454ac4;
border-color: #747af0;
box-shadow: 0 0 0 3px rgb(116 122 240 / 16%);
}
.org-node__name {
font-weight: 600;
}
.org-node__owner,
.org-node__count {
font-size: 12px;
color: #7a7f89;
}
.org-node__owner {
grid-column: 1 / -1;
}
</style>在树中使用
vue
<script setup lang="ts">
import type { PositionedNode } from '@org-tree/core'
import { ref } from 'vue'
const selectedNode = ref<PositionedNode>()
</script>
<template>
<OrgTreeProvider :sdk="sdk">
<OrgTree v-slot="{ node }">
<BusinessNodeCard
:node="node"
:selected="selectedNode?.nodeId === node.nodeId"
@select="selectedNode = $event"
/>
</OrgTree>
</OrgTreeProvider>
</template>与布局保持一致
配置中声明同一尺寸:
ts
layout: {
spaceX: 40,
spaceY: 56,
nodeSize: { width: 240, height: 104 },
}组件使用 node.width 和 node.height,就不会在后续调整布局配置时产生两套尺寸常量。
打开详情面板
PositionedNode.info 保留全部业务字段,可以把选中节点直接交给侧边栏:
vue
<NodeDetailDrawer
v-if="selectedNode"
:node="selectedNode"
@close="selectedNode = undefined"
/>业务点击不会替代 SDK 的展开按钮。用户仍可通过节点边缘的 + / − 控制子树。