Appearance
TreeSelector
성능을 고려하여 가상 스크롤이 적용된 다목적 트리 컴포넌트입니다.
개요
TreeSelector는 계층적 데이터를 트리 구조로 표시하며, 단일 선택과 다중 선택 모드를 지원합니다. 가상 스크롤링을 통해 대용량 데이터도 효율적으로 처리할 수 있습니다.
Props 인터페이스
typescript
interface Props<T = any> {
tree: TreeNode<T>[]; // 트리 데이터
multiSelect?: boolean; // 다중 선택 모드 (기본값: false)
leafIconForMultiSelect?: IconTypes; // 다중 선택 시 체크박스 표시할 아이콘 타입
width?: number; // 컴포넌트 너비 (기본값: 0 - 자동)
height?: number; // 컴포넌트 높이 (기본값: 300)
checkedKeys?: string[]; // 체크된 노드 키 목록 (기본값: [])
}
interface TreeNode<T = any> {
key: string; // 고유 키
label: string; // 표시 텍스트
children: TreeNode<T>[]; // 자식 노드들
fold?: boolean; // 접힘 상태 (기본값: false)
check?: boolean; // 체크 상태 (기본값: false)
disable?: boolean; // 비활성화 상태 (기본값: false)
icon?: IconTypes; // 노드 아이콘
data?: T; // 사용자 데이터
}
이벤트
fold
: 노드 접힘/펼침 시 발생 -(nodes: TreeNode<T>[]) => void
change
: 노드 선택 변경 시 발생 -(nodes: TreeNode<T>[]) => void
기본 사용법
vue
<template>
<TreeSelector
:tree="treeData"
:multi-select="false"
:width="300"
:height="400"
@change="onSelectionChange"
@fold="onNodeFold"
/>
</template>
<script setup lang="ts">
import { TreeSelector, type TreeNode } from '@jennifersoft/apm-components';
import { ICON_TYPE } from '@jennifersoft/vue-components-v2';
interface CustomData {
id: number;
name: string;
}
const treeData: TreeNode<CustomData>[] = [
{
key: '1',
label: 'Root Node',
icon: ICON_TYPE.folder,
data: { id: 1, name: 'root' },
children: [
{
key: '1-1',
label: 'Child Node',
icon: ICON_TYPE.file,
data: { id: 2, name: 'child' },
children: [],
},
],
},
];
const onSelectionChange = (nodes: TreeNode<CustomData>[]) => {
console.log('Selected nodes:', nodes);
};
const onNodeFold = (nodes: TreeNode<CustomData>[]) => {
console.log('Fold state changed:', nodes);
};
</script>
인터랙티브 데모
TreeSelector
사용 시나리오
1. 단일 선택 모드 (Single Selection)
단일 노드만 선택할 수 있는 기본 모드입니다.
vue
<template>
<TreeSelector
:tree="treeData"
:multi-select="false"
@change="onSingleSelect"
/>
</template>
<script setup>
const onSingleSelect = (nodes) => {
const selectedNode = nodes[0]; // 항상 하나의 노드만 선택됨
console.log('Selected:', selectedNode.label);
};
</script>
2. 다중 선택 모드 (Multi Selection)
여러 노드를 동시에 선택할 수 있습니다.
vue
<template>
<TreeSelector
:tree="treeData"
:multi-select="true"
@change="onMultiSelect"
/>
</template>
<script setup>
const onMultiSelect = (nodes) => {
console.log('Selected nodes count:', nodes.length);
nodes.forEach((node) => {
console.log('Selected:', node.label);
});
};
</script>
3. 제한된 다중 선택 (Leaf-only Multi Selection)
특정 아이콘을 가진 노드(주로 리프 노드)만 체크박스를 표시합니다.
vue
<template>
<TreeSelector
:tree="domainTreeData"
:multi-select="true"
:leaf-icon-for-multi-select="ICON_TYPE.domain"
@change="onDomainSelect"
/>
</template>
<script setup>
import { ICON_TYPE } from '@jennifersoft/vue-components-v2';
// domain 아이콘을 가진 노드만 선택 가능
const onDomainSelect = (nodes) => {
const domainIds = nodes.map((node) => node.data.domainId);
console.log('Selected domains:', domainIds);
};
</script>
4. 미리 체크된 상태로 시작
vue
<template>
<TreeSelector
:tree="treeData"
:multi-select="true"
:checked-keys="['node-1', 'node-3']"
@change="onPreCheckedChange"
/>
</template>
고급 기능
가상 스크롤링
대용량 트리 데이터의 성능을 위해 가상 스크롤링이 자동으로 적용됩니다.
vue
<template>
<!-- 수천 개의 노드도 부드럽게 렌더링 -->
<TreeSelector :tree="massiveTreeData" :height="400" />
</template>
커스텀 아이콘 사용
각 노드에 다양한 아이콘을 설정할 수 있습니다.
vue
<script setup>
import { ICON_TYPE } from '@jennifersoft/vue-components-v2';
const customTreeData = [
{
key: '1',
label: 'Server Group',
icon: ICON_TYPE.domainGroup,
children: [
{
key: '1-1',
label: 'Web Server',
icon: ICON_TYPE.domain,
children: [],
},
{
key: '1-2',
label: 'Database Server',
icon: ICON_TYPE.database,
children: [],
},
],
},
];
</script>
노드 상태 관리
vue
<script setup>
const treeDataWithStates = [
{
key: '1',
label: 'Active Node',
disable: false, // 활성화됨
fold: false, // 펼쳐짐
check: true, // 체크됨
children: [
{
key: '1-1',
label: 'Disabled Node',
disable: true, // 비활성화됨
children: [],
},
],
},
];
</script>
데이터 구조 예제
도메인/인스턴스 트리
typescript
interface DomainData {
domainId: number;
instanceId: number;
}
const domainTree: TreeNode<DomainData>[] = [
{
key: 'domain-1000',
label: 'Production',
icon: ICON_TYPE.domainGroup,
data: { domainId: 1000, instanceId: 0 },
children: [
{
key: 'instance-1001',
label: 'web-server-01',
icon: ICON_TYPE.domain,
data: { domainId: 1000, instanceId: 1001 },
children: [],
},
],
},
];
성능 최적화
- 가상 스크롤링: 대용량 데이터 처리
- 지연 로딩: 필요한 노드만 렌더링
- 메모리 효율성: 불필요한 DOM 노드 최소화
접근성 (Accessibility)
- 키보드 네비게이션 지원
- 스크린 리더 호환성
- ARIA 속성 자동 적용
의존성
- Vue 3 Composition API
@jennifersoft/vue-components-v2
(아이콘)- Virtual Scrolling 라이브러리 (내장)