Операции с деревом

Компонент n-tree в библиотеке Naive UI используется для визуализации и управления иерархическими структурами данных, такими как файловые системы, меню или организационные схемы. Его ключевые свойства позволяют создавать динамические деревья, настраивать отображение узлов, управлять их состоянием и реагировать на пользовательские действия.

import { createApp } from 'vue';
import { NTree } from 'naive-ui';

const treeData = [
  {
    key: 1,
    label: 'Корневой узел',
    children: [
      { key: 11, label: 'Дочерний узел 1' },
      { key: 12, label: 'Дочерний узел 2' }
    ]
  }
];

createApp({
  data() {
    return { treeData };
  },
  render() {
    return ;
  }
}).mount('#app');

Ключевые моменты:

  • nodes — массив объектов узлов с обязательными полями key и label.
  • children — массив дочерних узлов, рекурсивно формирующих дерево.
  • key должен быть уникальным, чтобы корректно отслеживать состояние каждого узла.

Динамическое добавление и удаление узлов

Для изменения структуры дерева на лету используются методы, которые изменяют массив nodes и перерисовывают компонент. Например, добавление нового узла к существующему:

function addNode(parentKey, newNode) {
  const findNode = (nodes) => {
    for (const node of nodes) {
      if (node.key === parentKey) return node;
      if (node.children) {
        const result = findNode(node.children);
        if (result) return result;
      }
    }
    return null;
  };
  
  const parentNode = findNode(treeData);
  if (!parentNode.children) parentNode.children = [];
  parentNode.children.push(newNode);
}

Удаление узла реализуется аналогично через рекурсивный поиск и фильтрацию массива children.


Управление состояниями узлов

Узел дерева может быть выбран, раскрыт или отмечен флажком. Управление состоянием осуществляется через свойства компонента:

  • expandedKeys — массив ключей раскрытых узлов.
  • selectedKeys — массив ключей выбранных узлов.
  • checkedKeys — массив ключей отмеченных узлов, используется с включённым checkable.

События, связанные с состояниями:

  • update:expanded-keys — вызывается при раскрытии/сворачивании узлов.
  • update:selected-keys — при изменении выбранного узла.
  • update:checked-keys — при отметке или снятии флажка.

Асинхронная загрузка узлов

Для больших деревьев удобно загружать дочерние узлы динамически, по мере раскрытия родительского узла. В Naive UI это реализуется через свойство loadChildren:

  • loadChildren должен возвращать массив узлов для текущего родителя.
  • Позволяет оптимизировать производительность при работе с большим количеством данных.

Кастомизация отображения узлов

С помощью слота label можно полностью контролировать визуальное представление узла:

 {node.label}
}} />

Возможности кастомизации включают:

  • Изменение текста, цвета, шрифта.
  • Добавление иконок и кнопок для управления узлом.
  • Встраивание других компонентов внутри каждого узла.

Drag & Drop и сортировка

Компонент поддерживает перетаскивание узлов с событиями onDragstart, onDragover, onDrop. Для включения функционала достаточно добавить соответствующие свойства и обработчики:

  • draggable — включает перетаскивание узлов.
  • Обработчики получают объект узла и информацию о позиции, куда он перемещается.
  • Позволяет реализовать сортировку и перемещение узлов внутри дерева.

Работа с фильтрацией и поиском

Фильтрация узлов дерева реализуется путём рекурсивного обхода и создания нового массива узлов, соответствующих критерию:

function filterTree(nodes, keyword) {
  return nodes
    .map(node => {
      if (node.label.includes(keyword)) return node;
      if (node.children) {
        const filteredChildren = filterTree(node.children, keyword);
        if (filteredChildren.length) return { ...node, children: filteredChildren };
      }
      return null;
    })
    .filter(Boolean);
}
  • Позволяет динамически обновлять nodes при вводе поискового запроса.
  • Можно комбинировать с раскрытием узлов, чтобы показать только релевантные ветки.

Оптимизация больших деревьев

При работе с большим количеством узлов рекомендуется:

  • Использовать асинхронную подгрузку дочерних узлов.
  • Применять виртуализацию (n-virtual-list) для отображения только видимой части дерева.
  • Ограничивать глубину раскрытия по умолчанию, чтобы не перегружать DOM.

Эти подходы позволяют сохранить высокую производительность интерфейса и минимизировать потребление ресурсов браузера.