Vue 트리 구조 시각화의 새로운 패러다임: vue-pure-admin TreeLine 컴포넌트 활용 가이드
【무료 다운로드 링크】vue-pure-admin 전체 ESM+Vue3+Vite+Element-Plus+TypeScript로 작성된 관리자 시스템 (모바일 호환) 프로젝트 주소: https://gitcode.com/GitHub_Trending/vu/vue-pure-admin
복잡한 계층 구조로 인해 어려움을 겪고 계신가요? 관리자 시스템에서 트리 구조를 효과적으로 표시하는 것은 중요한 과제입니다. 오늘 우리는 vue-pure-admin의 강력한 트리 연결선 컴포넌트인 TreeLine을 깊이 있게 살펴보겠습니다. 이 컴포넌트는 우아한 연결선 디자인을 통해 계층 관계를 명확히 시각화하여 사용자 경험을 향상시킵니다.
TreeLine 컴포넌트: 트리 구조의 혁신적 시각화
TreeLine(트리 연결선)은 vue-pure-admin 프레임워크의 강력한 커스텀 컴포넌트로, Element Plus의 트리 컴포넌트를 확장하여 직관적인 연결선을 추가합니다. 이를 통해 복잡한 계층 관계를 한눈에 파악할 수 있습니다. 이 컴포넌트는 element-tree-line을 최적화하고 Vue3+TypeScript로 재구성하여 더 나은 타입 지원과 유연한 옵션을 제공합니다.
TreeLine의 핵심 소스 코드는 src/components/ReTreeLine/index.ts에 위치하며, 스타일 정의는 src/components/ReTreeLine/index.scss에 있습니다. 커스텀 렌더링 함수를 통해 트리 노드 간에 연결선을 그리면서 Element Plus 트리 컴포넌트의 모든 기능을 유지합니다.
핵심 기능 분석: 계층 관계 시각화
1. 지능형 연결선 시스템
TreeLine의 가장 핵심적인 기능은 지능형 연결선 시스템입니다. 이 시스템은 노드가 부모 노드의 자식 노드 목록에서 위치를 자동으로 판단하여 정확한 연결선을 그립니다. 수직 및 수평 연결선 모두 정확하게 각 노드를 연결하여 계층 관계를 명확하게 보여줍니다.
// 각 레벨의 현재 노드가 해당 레벨 목록의 마지막 노드인지 확인
const lastnodeArr = [];
let currentNode: any = this.node;
while (currentNode) {
let parentNode: any = currentNode.parent;
// element-plus의 el-tree-v2 (Virtualized Tree)와 호환성
if (currentNode.level === 1 && !currentNode.parent) {
// el-tree-v2의 첫 번째 레벨 노드는 parent가 없으므로 treeData로 생성
if (!this.treeData || !Array.isArray(this.treeData)) {
throw Error(
"el-tree-v2 (Virtualized Tree)를 사용하는 경우, element-tree-line에 데이터가 필요합니다."
);
}
parentNode = {
children: Array.isArray(this.treeData)
? this.treeData.map(item => {
return { ...item, key: item.id };
})
: [],
level: 0,
key: "node-0",
parent: null
};
}
if (parentNode) {
// element-plus의 el-tree-v2는 children와 key를 사용, 다른 버전은 childNodes와 id 사용
const index = (parentNode.children || parentNode.childNodes).findIndex(
item => (item.key || item.id) === (currentNode.key || currentNode.id)
);
lastnodeArr.unshift(
index === (parentNode.children || parentNode.childNodes).length - 1
);
}
currentNode = parentNode;
}
2. 높은 수준의 커스터마이징
TreeLine 컴포넌트는 풍부한 스타일 커스터마이징 옵션을 제공하며, 프로젝트 요구사항에 맞게 연결선의 색상, 스타일 및 너비를 조정할 수 있습니다. SCSS 변수를 통해 테마 커스터마이징을 쉽게 구현할 수 있습니다:
$--element-tree-line-color: #dcdfe6 !default;
$--element-tree-line-style: dashed !default;
$--element-tree-line-width: 1px !default;
이러한 변수는 src/components/ReTreeLine/index.scss에 정의되어 있으며, 필요에 따라 수정하거나 컴포넌트 사용 시 CSS 변수를 오버라이드하여 개인화된 시각 효과를 구현할 수 있습니다.
3. 유연한 노드 콘텐츠 커스터마이징
TreeLine은 연결선을 최적화할 뿐만 아니라 유연한 노드 콘텐츠 커스터마이징 기능도 제공합니다. 슬롯(slot) 메커니즘을 통해 노드 라벨 콘텐츠를 커스터마이징하고 추가 정보를 삽입하거나 노드 구조를 완전히 재정의할 수 있습니다.
// 전체 노드 라벨 영역 커스터마이징
const scopeSlotDefault = this.getScopedSlot("default");
// 연결선 표시 시 노드 라벨 영역 커스터마이징
const labelSlot = this.getScopedSlot("node-label");
// 연결선 오른쪽에 추가될 콘텐츠
const afterLabelSlot = this.getScopedSlot("after-node-label");
이러한 유연한 디자인 덕분에 TreeLine은 간단한 분류 표시부터 복잡한 노드 작업까지 다양한 비즈니스 시나리오에 적용할 수 있습니다.
빠른 시작: 5분 만에 TreeLine 통합하기
1. 컴포넌트 등록
TreeLine 컴포넌트는 vue-pure-admin에서 전역으로 등록되어 있으므로, 추가적인 import 없이 모든 Vue 컴포넌트에서 직접 사용할 수 있습니다. 비전역 환경에서 사용하려면 다음과 같이 import할 수 있습니다:
import ReTreeLine from "@/components/ReTreeLine/index.ts";
2. 기본 사용법
TreeLine 사용은 매우 간단합니다. Element Plus의 el-tree 또는 el-tree-v2 컴포넌트에서 render-content 속성을 사용하여 TreeLine을 커스텀 렌더링 함수로 지정하기만 하면 됩니다:
<template>
<el-tree
:data="treeData"
:render-content="renderContent"
default-expand-all
></el-tree>
</template>
<script setup lang="ts">
import { h } from "vue";
import ReTreeLine from "@/components/ReTreeLine/index.ts";
const treeData = [
{
id: 1,
label: "1차 노드",
children: [
{
id: 2,
label: "2차 노드 1",
children: [
{ id: 3, label: "3차 노드 1" },
{ id: 4, label: "3차 노드 2" }
]
},
{ id: 5, label: "2차 노드 2" }
]
}
];
const renderContent = (h: any, context: any) => {
return h(ReTreeLine, {
node: context.node,
data: context.data,
treeData: treeData
});
};
</script>
3. 고급 설정
TreeLine은 다양한 설정 파라미터를 제공하여 컴포넌트 동작을 요구사항에 맞게 커스터마이징할 수 있습니다:
indent: 노드 들여쓰기 거리, 기본값 16pxshowLabelLine: 라벨 뒤의 연결선 표시 여부, 기본값 true
<template>
<el-tree
:data="treeData"
:render-content="renderContent"
default-expand-all
></el-tree>
</template>
<script setup lang="ts">
import { h } from "vue";
import ReTreeLine from "@/components/ReTreeLine/index.ts";
const treeData = [...];
const renderContent = (h: any, context: any) => {
return h(ReTreeLine, {
node: context.node,
data: context.data,
treeData: treeData,
indent: 20,
showLabelLine: false
});
};
</script>
실제 적용 사례: 이론에서 실전까지
TreeLine 컴포넌트는 실제 프로젝트에서 부서 구조, 파일 디렉토리, 권한 트리 등 계층 관계를 표시해야 하는 다양한 시나리오에 널리 적용됩니다. 몇 가지 구체적인 적용 사례를 살펴보겠습니다.
1. 부서 조직 구조 표시
관리자 시스템에서 회사의 부서 조직 구조를 표시하는 것은 흔한 요구사항입니다. TreeLine을 사용하면 부서 간의 계층 관계를 명확하게 표시하여 관리자들이 한눈에 파악할 수 있습니다.
<template>
<el-tree
:data="departmentData"
:render-content="renderContent"
default-expand-all
></el-tree>
</template>
<script setup lang="ts">
import { h } from "vue";
import ReTreeLine from "@/components/ReTreeLine/index.ts";
import { getDepartmentData } from "@/api/system/dept";
const departmentData = await getDepartmentData();
const renderContent = (h: any, context: any) => {
return h(ReTreeLine, {
node: context.node,
data: context.data,
treeData: departmentData
}, {
"node-label": (scope: any) => {
return h("div", [
h("span", scope.node.label),
h("el-tag", { size: "small", style: "margin-left: 10px" }, scope.data.employeeCount + "명")
]);
}
});
};
</script>
이 예제에서는 부서 계층 관계를 표시할 뿐만 아니라 "node-label" 슬롯을 커스터마이징하여 부서 이름 뒤에 해당 부서의 직원 수를 추가하여 더 풍부한 정보를 제공합니다.
2. 권한 관리 트리 구조
권한 관리는 관리자 시스템의 핵심 기능 중 하나로, 일반적으로 트리 구조를 사용하여 권한의 계층 관계를 표시합니다. TreeLine은 사용자가 권한 간의 상속 관계를 더 직관적으로 이해하도록 도움을 줍니다.
<template>
<el-tree
:data="permissionData"
:render-content="renderContent"
show-checkbox
default-expand-all
></el-tree>
</template>
<script setup lang="ts">
import { h } from "vue";
import ReTreeLine from "@/components/ReTreeLine/index.ts";
import { getPermissionTree } from "@/api/system/permission";
const permissionData = await getPermissionTree();
const renderContent = (h: any, context: any) => {
return h(ReTreeLine, {
node: context.node,
data: context.data,
treeData: permissionData
}, {
"after-node-label": (scope: any) => {
return scope.data.isEnabled ?
h("el-tag", { size: "small", type: "success" }, "활성화") :
h("el-tag", { size: "small", type: "danger" }, "비활성화");
}
});
};
</script>
이 예제에서는 "after-node-label" 슬롯을 사용하여 권한 이름 뒤에 상태 태그를 추가하여 해당 권한이 활성화되었는지 여부를 직관적으로 표시합니다.
커스터마이징 가이드: 맞춤형 트리 스타일 만들기
TreeLine 컴포넌트는 연결선 스타일과 노드 표시 방식을 프로젝트 요구사항에 맞게 조정할 수 있는 풍부한 커스터마이징 옵션을 제공합니다. 일반적인 커스터마이징 요구사항과 구현 방법을 소개합니다.
1. 연결선 스타일 변경
TreeLine의 연결선 스타일은 SCSS 변수를 수정하여 변경할 수 있습니다. src/components/ReTreeLine/index.scss 파일을 열면 다음 변수 정의를 볼 수 있습니다:
$--element-tree-line-color: #dcdfe6 !default;
$--element-tree-line-style: dashed !default;
$--element-tree-line-width: 1px !default;
이 변수 값을 직접 수정하거나 컴포넌트 사용 시 CSS로 오버라이드할 수 있습니다:
/* 컴포넌트 스타일에서 */
:deep(.element-tree-node-line-ver) {
border-left: 1px solid #409eff;
}
:deep(.element-tree-node-line-hor) {
border-bottom: 1px solid #409eff;
}
2. 노드 아이콘 커스터마이징
"node-label" 슬롯을 커스터마이징하여 다른 유형의 노드에 다른 아이콘을 추가할 수 있습니다:
<template>
<el-tree
:data="menuData"
:render-content="renderContent"
default-expand-all
></el-tree>
</template>
<script setup lang="ts">
import { h } from "vue";
import ReTreeLine from "@/components/ReTreeLine/index.ts";
import { ReIcon } from "@/components/ReIcon";
const menuData = [...];
const renderContent = (h: any, context: any) => {
return h(ReTreeLine, {
node: context.node,
data: context.data,
treeData: menuData
}, {
"node-label": (scope: any) => {
return h("div", { style: "display: flex; align-items: center" }, [
h(ReIcon, {
icon: scope.data.icon || "folder",
style: "margin-right: 8px"
}),
h("span", scope.node.label)
]);
}
});
};
</script>
이 예제에서는 vue-pure-admin의 ReIcon 컴포넌트를 사용하여 노드 데이터의 icon 필드에 따라 다른 메뉴 노드에 다른 아이콘을 표시합니다.
3. 드래그 앤 드롭 기능 구현
Element Plus 트리 컴포넌트의 드래그 앤 드롭 기능과 TreeLine의 연결선을 결합하여 계층 관계가 직관적이면서도 드래그 정렬이 가능한 트리 컴포넌트를 구현할 수 있습니다:
<template>
<el-tree
:data="menuData"
:render-content="renderContent"
draggable
:allow-drop="allowDrop"
@node-drop="handleNodeDrop"
default-expand-all
></el-tree>
</template>
<script setup lang="ts">
import { h, ref } from "vue";
import ReTreeLine from "@/components/ReTreeLine/index.ts";
import { getMenuData, updateMenuOrder } from "@/api/system/menu";
const menuData = ref(await getMenuData());
const renderContent = (h: any, context: any) => {
return h(ReTreeLine, {
node: context.node,
data: context.data,
treeData: menuData.value
});
};
const allowDrop = (draggingNode: any, dropNode: any, type: any) => {
// 커스텀 드래그 규칙 구현
return true;
};
const handleNodeDrop = async (draggingNode: any, dropNode: any, dropType: any) => {
// API 호출하여 메뉴 순서 업데이트
await updateMenuOrder({
id: draggingNode.data.id,
parentId: dropNode.data.id,
sort: dropType === "before" ? dropNode.data.sort - 1 : dropNode.data.sort + 1
});
// 메뉴 데이터 다시 로드
menuData.value = await getMenuData();
};
</script>
이 예제는 TreeLine을 트리 컴포넌트의 드래그 앤 드롭 기능과 결합하여 드래그 정렬이 가능한 메뉴 관리 기능을 구현하는 방법을 보여줍니다. 사용자가 노드를 드래그하여 순서를 조정하면 시스템이 새 순서를 저장하고 데이터를 다시 로드하여 TreeLine 연결선이 올바르게 표시되도록 합니다.
결론 및 전망
TreeLine 컴포넌트는 vue-pure-admin 프레임워크의 중요한 구성 요소로, 직관적인 연결선 디자인을 통해 트리 구조의 시각적 효과와 사용자 경험을 크게 향상시킵니다. 풍부한 기능과 유연한 설정 옵션을 제공하면서도 Element Plus 트리 컴포넌트와 완벽하게 호환되므로 개발자들이 쉽게 익히고 프로젝트에 통합할 수 있습니다.
vue-pure-admin 프레임워크의 지속적인 발전과 함께 TreeLine 컴포넌트는 커스텀 연결선 스타일, 애니메이션 효과, 노드 상태 시각화 등 더 많은 강력한 기능을 제공할 것으로 기대됩니다. 초보 개발자든 경험 많은 개발자든 TreeLine은 더 전문적이고 직관적인 트리 구조 인터페이스를 구축하는 데 도움을 줄 것입니다.
【무료 다운로드 링크】vue-pure-admin 전체 ESM+Vue3+Vite+Element-Plus+TypeScript로 작성된 관리자 시스템 (모바일 호환) 프로젝트 주소: https://gitcode.com/GitHub_Trending/vu/vue-pure-admin