Фильтрация дерева — одна из ключевых возможностей компонента
ElTree в библиотеке Element Plus,
позволяющая пользователям динамически искать и отображать узлы на основе
заданного критерия. Это особенно актуально при работе с большими
иерархическими структурами данных, где необходимо скрывать лишние ветви
и выделять релевантные элементы.
Данные для дерева должны быть организованы в виде массива объектов с обязательными свойствами:
id — уникальный идентификатор
узла.label — текст, который отображается в
дереве.children — массив дочерних узлов (если
есть).Пример структуры данных:
const treeData = [
{
id: 1,
label: 'Фрукты',
children: [
{ id: 11, label: 'Яблоки' },
{ id: 12, label: 'Апельсины' }
]
},
{
id: 2,
label: 'Овощи',
children: [
{ id: 21, label: 'Морковь' },
{ id: 22, label: 'Брокколи' }
]
}
];
Ключевой момент: фильтрация работает только с текущими
данными дерева, поэтому любые динамические изменения в массиве
treeData должны быть отражены в компоненте через
реактивность Vue.
Компонент ElTree предоставляет метод
filter, который позволяет задавать функцию
фильтрации:
<el-tree
:data="treeData"
:props="{ children: 'children', label: 'label' }"
ref="treeRef"
>
</el-tree>
В JavaScript-файле:
const treeRef = ref(null);
const filterNode = (value, data) => {
if (!value) return true;
return data.label.toLowerCase().includes(value.toLowerCase());
};
const applyFilter = (searchText) => {
treeRef.value.filter(searchText);
};
Особенности работы метода filter:
true для узлов, которые должны остаться
видимыми.Для реализации интерактивного поиска часто используется связка с
v-model:
<el-input
v-model="searchText"
placeholder="Введите название"
@input="applyFilter(searchText)"
></el-input>
<el-tree
:data="treeData"
:props="{ children: 'children', label: 'label' }"
ref="treeRef"
></el-tree>
const searchText = ref('');
watch(searchText, (newVal) => {
treeRef.value.filter(newVal);
});
Преимущество такого подхода — мгновенное обновление дерева при вводе текста, без необходимости ручного обновления состояния.
Метод filter не ограничен простой проверкой строки.
Можно фильтровать по любому полю узла или по сложной логике:
const customFilter = (value, data) => {
if (!value) return true;
// Показываем только узлы с id больше 10, если строка поиска совпадает
return data.label.includes(value) && data.id > 10;
};
treeRef.value.filter(customFilter);
Ключевой момент: функция фильтрации вызывается для каждого узла, включая дочерние элементы. Для больших деревьев рекомендуется оптимизировать логику, чтобы избежать падения производительности.
default.filter('')
восстанавливает исходное дерево.Пример с подсветкой:
<el-tree
:data="treeData"
:props="{ children: 'children', label: 'label' }"
ref="treeRef"
>
<template #default="{ node, data }">
<span :class="{ highlight: data.label.includes(searchText) }">{{ data.label }}</span>
</template>
</el-tree>
.highlight {
background-color: yellow;
}
Для деревьев с ленивой загрузкой (lazy):
Пример:
const loadNode = (node, resolve) => {
setTimeout(() => {
if (node.level === 0) {
resolve([
{ id: 1, label: 'Фрукты', isLeaf: false },
{ id: 2, label: 'Овощи', isLeaf: false }
]);
} else if (node.data.label === 'Фрукты') {
resolve([{ id: 11, label: 'Яблоки' }, { id: 12, label: 'Апельсины' }]);
} else {
resolve([]);
}
}, 500);
};
<el-tree
:data="[]"
:props="{ children: 'children', label: 'label', isLeaf: 'isLeaf' }"
:load="loadNode"
lazy
ref="treeRef"
></el-tree>
В такой схеме фильтрация требует дополнительно загрузить все
возможные узлы, чтобы функция filter могла
проверить соответствие каждого элемента.
Фильтрация дерева в Element Plus предоставляет
гибкие возможности для поиска, скрытия и выделения узлов. Благодаря
методу filter и поддержке кастомных функций можно
реализовать как простой поиск по строке, так и сложные условия на основе
любых данных узла. В сочетании с реактивностью Vue и слотами для
кастомного рендеринга, фильтрация становится мощным инструментом для
создания интерактивных интерфейсов с иерархическими структурами.