Выбор узлов

В Element Plus управление выбором узлов реализуется через компоненты типа el-tree, el-select и их расширенные возможности. Понимание того, как правильно управлять выбранными элементами, критично для построения динамических интерфейсов и работы с иерархическими данными.


Компонент el-tree и выбор узлов

Компонент el-tree предоставляет мощные средства для работы с древовидными структурами. Основные свойства, отвечающие за выбор узлов:

  • show-checkbox – отображает чекбоксы рядом с узлами.
  • check-strictly – задаёт независимость выбора узлов и их потомков. Если false, выбор родителя автоматически выбирает всех потомков, и наоборот.
  • default-checked-keys – массив ключей узлов, которые должны быть выбраны при инициализации дерева.
  • check-descendants – позволяет автоматически проверять дочерние узлы при выборе родителя.

Пример инициализации дерева с выбором:

<template>
  <el-tree
    :data="treeData"
    show-checkbox
    node-key="id"
    default-checked-keys="[1, 3]"
    check-strictly
    @check-change="handleCheckChange">
  </el-tree>
</template>

<script>
export default {
  data() {
    return {
      treeData: [
        { id: 1, label: 'Узел 1', children: [
          { id: 2, label: 'Узел 1-1' },
          { id: 3, label: 'Узел 1-2' }
        ]},
        { id: 4, label: 'Узел 2' }
      ]
    };
  },
  methods: {
    handleCheckChange(node, checked, indeterminate) {
      console.log('Выбран узел:', node, 'Статус:', checked);
    }
  }
};
</script>

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

  • node-key необходим для корректного отслеживания выбранных элементов.
  • Событие check-change срабатывает при каждом изменении состояния узла, предоставляя объект узла и статус выбора.
  • При использовании check-strictly, выбор родителя не затрагивает детей, что позволяет гибко контролировать состояние дерева.

Получение выбранных узлов

Для доступа к текущему списку выбранных элементов используется метод getCheckedNodes():

this.$refs.tree.getCheckedNodes();

Если нужно учитывать только полностью выбранные узлы без частично отмеченных (indeterminate), передаётся аргумент true:

const fullyChecked = this.$refs.tree.getCheckedNodes(true);

Для получения ключей выбранных узлов применяется getCheckedKeys():

const checkedKeys = this.$refs.tree.getCheckedKeys();

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


Управление выбором программно

Выбор и снятие выбора узлов можно выполнять программно через методы:

  • setChecked(nodeKey, checked, deep) – выбирает или снимает выбор с узла по ключу. Если deep установлен в true, действие распространяется на всех потомков.
  • toggleCheck(nodeKey) – переключает состояние выбора узла.

Пример:

// Выбрать узел с ключом 2 и всех его потомков
this.$refs.tree.setChecked(2, true, true);

// Снять выбор только с конкретного узла
this.$refs.tree.setChecked(3, false);

Это особенно полезно при динамическом изменении данных или применении логики фильтров.


Ленивая загрузка и выбор узлов

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

  • Указывать lazy и функцию load для асинхронного получения потомков.
  • Вызывать методы выбора после завершения загрузки дочерних узлов.

Пример ленивой загрузки с выбором:

<el-tree
  :data="treeData"
  lazy
  :load="loadNode"
  show-checkbox
  ref="tree">
</el-tree>

methods: {
  loadNode(node, resolve) {
    setTimeout(() => {
      resolve([
        { id: node.id + '-1', label: 'Дочерний узел' }
      ]);
    }, 500);
  },
  selectNode(id) {
    this.$refs.tree.setChecked(id, true);
  }
}

Взаимодействие с el-select для выбора узлов

При комбинировании el-tree с el-select для выбора нескольких узлов создаются комбинированные селекты. Основная логика:

  • el-select используется для отображения выбранных узлов в виде тегов.
  • el-tree управляет внутренним состоянием выбранных элементов.
  • Связка реализуется через двустороннюю привязку (v-model) и методы дерева (getCheckedNodes()).

Пример интеграции:

<el-select v-model="selectedNodes" multiple placeholder="Выберите узлы">
  <el-option
    v-for="node in flatTree"
    :key="node.id"
    :label="node.label"
    :value="node.id">
  </el-option>
</el-select>

Для поддержки иерархического выбора можно использовать рекурсивное преобразование дерева в плоский массив с сохранением связей родитель-дитя.


Практические советы по выбору узлов

  1. Использовать node-key для уникальной идентификации – это предотвращает ошибки при программном управлении выбором.
  2. Выбирать между строгим и нестрогим режимом выбора (check-strictly) в зависимости от UX.
  3. Сохранять состояние выборов при ленивой загрузке через хранение ключей выбранных узлов и повторное применение после подгрузки.
  4. Синхронизировать с внешними компонентами (el-select, формы) через события и методы getCheckedNodes() и setChecked().
  5. Использовать глубокое управление выбором (deep) для автоматической установки статуса всех потомков при выборе родителя.

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