Element Plus предоставляет гибкий механизм для работы с деревьями
компонентов через компонент ElTree. Одним
из самых мощных инструментов является возможность использования
пользовательских шаблонов узлов, что позволяет полностью
контролировать отображение каждого элемента дерева.
По умолчанию ElTree отображает дерево, используя простой
текст из поля label объекта данных. Чтобы кастомизировать
отображение, применяется слот default для
узлов:
<el-tree
:data="treeData"
node-key="id"
:props="defaultProps"
>
<template #default="{ node, data }">
<div style="display: flex; align-items: center;">
<span style="font-weight: bold;">{{ data.label }}</span>
<span style="margin-left: auto; color: gray;">{{ data.info }}</span>
</div>
</template>
</el-tree>
Ключевые моменты:
node — объект TreeNode, содержащий
информацию о состоянии узла, включая методы для раскрытия/сворачивания,
выбранного состояния и т.д.data — оригинальный объект из массива
treeData.default позволяет использовать любую HTML-разметку
и Vue-компоненты внутри узла.Для сложных интерфейсов удобно рендерить разные компоненты внутри узлов, в зависимости от типа данных:
<el-tree :data="treeData" node-key="id" :props="defaultProps">
<template #default="{ node, data }">
<component :is="getComponent(data.type)" :data="data" />
</template>
</el-tree>
<script>
import FileNode from './components/FileNode.vue';
import FolderNode from './components/FolderNode.vue';
export default {
methods: {
getComponent(type) {
return type === 'file' ? FileNode : FolderNode;
}
}
}
</script>
Такой подход позволяет поддерживать разные визуальные представления узлов, при этом сохраняя функциональность дерева.
Через объект node доступны методы и свойства для
управления узлом:
node.expanded — проверка состояния раскрытия.node.level — уровень вложенности.node.setChecked(boolean) — программная установка
состояния выбора.node.isLeaf — проверка, является ли узел листом.node.parent — родительский узел.Пример условного изменения стиля для раскрытых узлов:
<template #default="{ node, data }">
<div :style="{ backgroundColor: node.expanded ? '#f0f9eb' : '#fff' }">
{{ data.label }}
</div>
</template>
Element Plus позволяет полностью переопределять иконки
раскрытия через слот toggle:
<el-tree :data="treeData" node-key="id" :props="defaultProps">
<template #toggle="{ node }">
<i v-if="node.expanded" class="el-icon-minus"></i>
<i v-else class="el-icon-plus"></i>
</template>
<template #default="{ node, data }">
{{ data.label }}
</template>
</el-tree>
toggle заменяет стандартную стрелку на любую
иконку или компонент.Часто требуется подгружать данные динамически. Для этого используется
событие load в комбинации с пользовательским шаблоном:
<el-tree
:data="treeData"
:props="defaultProps"
:load="loadNode"
lazy
node-key="id"
>
<template #default="{ node, data }">
<span>{{ data.label }}</span>
<span v-if="node.loading" style="color: gray;">Загрузка...</span>
</template>
</el-tree>
<script>
export default {
methods: {
loadNode(node, resolve) {
setTimeout(() => {
resolve([
{ id: node.data.id + '-1', label: 'Дочерний узел' }
])
}, 1000);
}
}
}
</script>
lazy — активирует ленивую загрузку.resolve — функция для передачи загруженных данных
обратно дереву.node.loading можно использовать для
отображения индикатора загрузки прямо в пользовательском шаблоне.С помощью пользовательского шаблона можно навешивать события на отдельные элементы:
<template #default="{ node, data }">
<div @click="onClickNode(node, data)" style="cursor: pointer;">
{{ data.label }}
</div>
</template>
<script>
export default {
methods: {
onClickNode(node, data) {
console.log('Выбран узел:', data.label);
node.setChecked(!node.checked);
}
}
}
</script>
node.setChecked позволяет изменять состояние выбора без
модификации исходного массива данных.Использование :class и :style прямо в слоте
default позволяет стилизовать узлы в зависимости от
условий:
<template #default="{ node, data }">
<div
:class="{ 'is-selected': node.checked }"
:style="{ color: data.type === 'folder' ? 'blue' : 'black' }"
>
{{ data.label }}
</div>
</template>
Элементы интерфейса Element Plus можно внедрять прямо в узлы:
<template #default="{ data }">
<el-tag type="success">{{ data.label }}</el-tag>
</template>
el-button, el-badge,
el-avatar.Пользовательские шаблоны узлов предоставляют полную свободу
кастомизации и позволяют строить комплексные интерфейсы на базе
ElTree, сохраняя при этом функциональность
управления состоянием узлов и событийную логику.