Appearance
Tree
Tree 컴포넌트는 디렉터리, 조직도, 분류 체계 등 계층적인 구조의 데이터를 표현할 때 사용합니다. 사용자는 각 노드를 확장하거나 축소하고, 선택할 수 있어 구조를 직관적으로 탐색할 수 있습니다.
Tree
RnD 대시보드 모음
David 대시보드
기술지원
싸이웰 시스템
지티플러스
이인티그레이션
Aiden 대시보드
vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import { Tree } from '@jennifersoft/vue-components-v2';
const treeData = ref([
{
label: 'RnD 대시보드 모음',
dashboard_ids: ['dashboard_id1', 'dashboard_id2', 'dashboard_id3'],
isOpen: true,
id: 'id1',
children: [
{
label: 'David 대시보드',
id: 'id2',
isOpen: true,
children: [
{
label: '기술지원',
id: 'id3',
isOpen: true,
dashboard_ids: [
'dashboard_id4',
'dashboard_id5',
'dashboard_id6',
],
children: [
{
label: '싸이웰 시스템',
id: 'id4',
dashboard_ids: ['dashboard_id7'],
},
{
label: '지티플러스',
id: 'id5',
dashboard_ids: ['dashboard_id8'],
},
{
label: '이인티그레이션',
id: 'id6',
dashboard_ids: ['dashboard_id9'],
},
],
},
],
},
{
label: 'Aiden 대시보드',
id: 'id7',
children: [
{
label: '기술지원',
id: 'id8',
dashboard_ids: [
'dashboard_id10',
'dashboard_id11',
'dashboard_id12',
],
},
],
},
],
},
]);
const selectedId = ref('id3');
</script>
<template>
<tree :nodes="treeData" v-model="selectedId" />
</template>Props
| Prop 이름 | 타입 | 필수 여부 | 기본값 | 설명 |
|---|---|---|---|---|
| nodes | TreeNodeData[] | Yes | - | 트리 노드 데이터 배열 |
| treeType | 'default' | 'folder' | 'icon' | No | 'default' | 트리 표시 타입 |
| searchText | string | No | '' | 모든 깊이의 노드 이름에서 강조할 검색어 |
v-model
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| (기본) | string | null | null | 선택된 노드의 id 바인딩 |
이벤트
| 이벤트 이름 | 파라미터 | 설명 |
|---|---|---|
| node-click | node: TreeNodeData | 노드 클릭 시 발생 |
검색어 강조
searchText를 전달하면 노드 이름에서 일치하는 부분을 노란색으로 강조합니다. 아래 검색어를 바꾸면 모든 깊이의 노드에 적용되는 강조 표시를 확인할 수 있습니다.
API services
api.backend
api-api-01
background-worker
vue
<script setup lang="ts">
import { ref } from 'vue';
import { InputSearch, Tree, type TreeNodeData } from '@jennifersoft/vue-components-v2';
const searchText = ref<string | undefined>('api');
const selectedId = ref<string | null>(null);
const nodes = ref<TreeNodeData[]>([
{
id: 'services',
label: 'API services',
isOpen: true,
children: [
{
id: 'backend',
label: 'api.backend',
isOpen: true,
children: [{ id: 'pod', label: 'api-api-01' }],
},
{ id: 'worker', label: 'background-worker' },
],
},
]);
</script>
<template>
<InputSearch v-model="searchText" size="small" placeholder="강조할 검색어" />
<Tree
v-model="selectedId"
:nodes="nodes"
tree-type="default"
:search-text="searchText"
/>
</template>- 대소문자를 구분하지 않고 겹치지 않는 모든 일치 구간을 강조합니다.
api-api-01에서api는 두 군데 모두 강조됩니다. .,[,*같은 특수문자와 공백도 입력된 문자 그대로 취급합니다. 앞뒤 공백을 무시하려면:search-text="(searchText ?? '').trim()"으로 전달합니다.- 검색어를 지우거나
searchText를 생략하면 일반 텍스트로 표시합니다.InputSearch가 지우기 동작에서 전달하는undefined에도 기본값''가 적용됩니다. searchText는 강조 표시만 담당합니다. 노드 필터링과 검색 결과의 자동 펼치기는 호출 화면에서 처리해야 합니다.- 기존 선택, 펼치기/접기, 말줄임 표시를 유지하며, 일치 위치로 자동 스크롤하지 않습니다.
Icon Tree
ryan
ryan-dash
ryan-k8s-1011
ryan-k8s-1012
ryan-k8s-1013
ryan-k8s-1014
Total
jennifer
infra
Demian
vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import { Tree } from '@jennifersoft/vue-components-v2';
import { ICON_TYPE } from '@jennifersoft/vue-components-v2';
const customIconTreeData = ref([
{
label: 'ryan',
isOpen: true,
id: 'id1',
icon: ICON_TYPE.domainGroup,
children: [
{
label: 'ryan-dash',
id: 'id2',
icon: ICON_TYPE.domain,
},
{
label: 'ryan-k8s-1011',
id: 'id3',
icon: ICON_TYPE.domain,
},
{
label: 'ryan-k8s-1012',
id: 'id4',
icon: ICON_TYPE.domain,
},
{
label: 'ryan-k8s-1013',
id: 'id5',
icon: ICON_TYPE.domain,
},
{
label: 'ryan-k8s-1014',
id: 'id6',
icon: ICON_TYPE.domain,
},
],
},
{
label: 'Total',
isOpen: true,
id: 'id7',
icon: ICON_TYPE.domainGroup,
children: [
{
label: 'jennifer',
id: 'id8',
icon: ICON_TYPE.domainGroup,
children: [
{
label: 'autodeploy',
id: 'id8-1',
icon: ICON_TYPE.domain,
},
{
label: 'webflux',
id: 'id8-2',
icon: ICON_TYPE.domain,
},
],
},
{
label: 'infra',
id: 'id10',
icon: ICON_TYPE.domainGroup,
children: [
{
label: 'simula',
id: 'id11',
icon: ICON_TYPE.domain,
},
{
label: 'ENV_TEST',
id: 'id12',
icon: ICON_TYPE.domain,
},
{
label: 'Jennifer5',
id: 'id13',
icon: ICON_TYPE.domain,
},
],
},
{
label: 'Demian',
id: 'id20',
icon: ICON_TYPE.domainGroup,
children: [
{
label: 'Demian background',
id: 'id21',
icon: ICON_TYPE.domain,
},
{
label: 'Demian collector',
id: 'id22',
icon: ICON_TYPE.domain,
},
{
label: 'Demian console',
id: 'id23',
icon: ICON_TYPE.domain,
},
],
},
],
},
]);
const selectedId = ref('id3');
</script>
<template>
<tree :nodes="customIconTreeData" v-model="selectedId" tree-type="icon" />
</template>Folder Tree
RnD 대시보드 모음
David 대시보드
기술지원
싸이웰 시스템
지티플러스
이인티그레이션
Aiden 대시보드
vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import { Tree } from '@jennifersoft/vue-components-v2';
const treeData = ref([
{
label: 'RnD 대시보드 모음',
dashboard_ids: ['dashboard_id1', 'dashboard_id2', 'dashboard_id3'],
isOpen: true,
id: 'id1',
children: [
{
label: 'David 대시보드',
id: 'id2',
isOpen: true,
children: [
{
label: '기술지원',
id: 'id3',
isOpen: true,
dashboard_ids: [
'dashboard_id4',
'dashboard_id5',
'dashboard_id6',
],
children: [
{
label: '싸이웰 시스템',
id: 'id4',
dashboard_ids: ['dashboard_id7'],
},
{
label: '지티플러스',
id: 'id5',
dashboard_ids: ['dashboard_id8'],
},
{
label: '이인티그레이션',
id: 'id6',
dashboard_ids: ['dashboard_id9'],
},
],
},
],
},
{
label: 'Aiden 대시보드',
id: 'id7',
children: [
{
label: '기술지원',
id: 'id8',
dashboard_ids: [
'dashboard_id10',
'dashboard_id11',
'dashboard_id12',
],
},
],
},
],
},
]);
const selectedId = ref('id3');
</script>
<template>
<tree :nodes="treeData" v-model="selectedId" tree-type="folder" />
</template>