Skip to content

ScTree

트리형 UI를 구성할 때 사용하는 컴포넌트입니다. 트리 선택 후 오른쪽 영역에서 수정/삭제가 가능한 형태로 구성되어 있습니다. v-model을 통해 전체 트리 데이터를 바인딩하며, 선택된 노드를 @select 이벤트를 통해 처리할 수 있습니다.

기본 예제

메뉴 ID
부모 메뉴 ID
메뉴명
vue
<div class="flex gap-5">
  <div class="w-[350px]">
    <sc-tree ref="treeRef" v-model="tree" @select="onSelect" />
  </div>
  <div class="flex-1">
    <div class="mb-2 text-right">
      <sc-button size="small" @click="onSave" :disabled="!['new', 'modify'].includes(status)">
        저장
      </sc-button>
      <sc-button size="small" :disabled="['none'].includes(status)" @click="onDelete">
        삭제
      </sc-button>
    </div>
    <sc-validator ref="validator">
      <sc-form-box col="1">
        <sc-form-item label="메뉴 ID" required>
          <sc-text-field v-if="selectNode === null" disabled />
          <sc-text-field
            v-else
            v-model="selectNode.replaceKey"
            :rules="[ruleRequired]"
          ></sc-text-field>
        </sc-form-item>
        <sc-form-item label="부모 메뉴 ID" required>
          <sc-text-field v-if="selectNode === null" disabled />
          <sc-text-field v-else v-model="selectNode.parentKey" disabled></sc-text-field>
        </sc-form-item>
        <sc-form-item label="메뉴명" required>
          <sc-text-field v-if="selectNode === null" disabled />
          <sc-text-field
            v-else
            v-model="selectNode.name"
            :rules="[ruleRequired, ruleMinLength(selectNode.name, 1)]"
          ></sc-text-field>
        </sc-form-item>
      </sc-form-box>
    </sc-validator>
  </div>
</div>

<script setup>
import { ref } from 'vue';
import { useRules } from '@/hooks/common/useRules.js';
const { ruleRequired, ruleMinLength } = useRules();

// 컴포넌트 참조를 위한 ref
const treeRef = ref(null);
const validator = ref(null);
const selectNode = ref(null);

const status = ref('none'); // none, new, modify

const tree = ref({
  treeInfo: {
    key: 'MENU',
    name: 'MENU',
    // searched: false,
    // selected: false,
    // checked: false,
    // hasChild: true,
    expanded: false,
    // inlineEdit: false,
  },
  children: [
    {
      treeInfo: {
        key: 'G0',
        parentKey: 'MENU',
        name: '업무함',
        depth: 2,
        seq: 10,
        searched: false,
        selected: false,
        checked: false,
        hasChild: true,
        expanded: false,
        inlineEdit: false,
      },
      children: [
        {
          treeInfo: {
            key: 'G0A012',
            parentKey: 'G0',
            name: '작성중',
            depth: 3,
            seq: 10,
            searched: false,
            selected: false,
            checked: false,
            hasChild: false,
            expanded: false,
            inlineEdit: false,
          },
          children: [],
        },
        {
          treeInfo: {
            key: 'G0A016',
            parentKey: 'G0',
            name: '미결함',
            depth: 3,
            seq: 20,
            searched: false,
            selected: false,
            checked: false,
            hasChild: false,
            expanded: false,
            inlineEdit: false,
          },
          children: [],
        },
        // 생략
      ],
    },
  ],
});

const onSelect = (node) => {
  // 선택한게 없음
  if (node === null) {
    status.value = 'none';
    selectNode.value = null;
    return;
  }
  selectNode.value = {
    ...node,
    replaceKey: node.key,
  }; // 직접 할당이 아닌 복사를 해야 key변경시 tree 확인이 필요

  if (node.key === '') {
    // 신규
    status.value = 'new';
  } else if (node.key) {
    // 수정
    status.value = 'modify';
  }
};

const onSave = () => {
  const isValid = validator.value.validateAll();
  if (isValid) {
    // 모두 validation이 통과 되었을 경우 로직
    console.info('save', selectNode.value);
  }
};

const onDelete = () => {
  // delete validation check 후 삭제로직 (하위 차일드 존재여부 체크)
  treeRef.value.remove(selectNode.value, () => {
    // 삭제로직
    console.info('API 로 실제 삭제 로직 실행 axios');
  });
};
</script>

주요 Props

Prop설명
v-model전체 트리 구조를 바인딩
ref="tree"삭제 시 내부 remove 호출 가능
@select트리 노드 선택 이벤트 발생

이벤트

이벤트명설명
@select트리 노드를 선택할 때 발생

Tree 노드 구조 (treeInfo)

속성명설명
key고유 ID
parentKey부모 노드의 key
name표시될 텍스트
depth트리의 깊이 정보
expanded하위 트리 열림 여부
selected선택 여부
hasChild자식 존재 여부
inlineEdit인라인 편집 여부