在 Element UI 的 el-tree-select
中同时实现动态加载(懒加载)和搜索功能,需要协调好懒加载逻辑与搜索逻辑,避免两者冲突。以下是实现思路和代码示例:
核心问题分析
- 动态加载(
lazy + load
):通过load
方法按需加载子节点,适合数据量大的树形结构 - 搜索功能(
filterable + remote-method
):需要根据关键词筛选节点,可能需要后端配合
解决方案
- 搜索时使用远程搜索模式,直接从后端获取匹配的节点(完整树形结构)
- 非搜索状态下恢复懒加载模式,保持按需加载特性
- 维护两种状态的数据和加载逻辑,确保切换流畅
<template><el-tree-selectv-model="queryForm.eventType"placeholder="请选择事件类型"check-on-click-nodefilterable:remote-method="handleRemoteSearch":loading="eventTypeLoading"check-strictly:lazy="!isSearching" <!-- 搜索时关闭懒加载 -->:load="getEventTree":data="isSearching ? searchResult : treeData" <!-- 根据状态切换数据源 -->:props="{label: 'label',children: 'children',isLeaf: 'isLeaf',}"clearable@clear="handleClearSearch" <!-- 清空搜索时恢复懒加载 -->/>
</template><script>
export default {data() {return {queryForm: {eventType: null},eventTypeLoading: false,treeData: [], // 懒加载模式下的根节点数据searchResult: [], // 搜索结果数据isSearching: false // 标记是否处于搜索状态};},methods: {// 初始化根节点数据(懒加载的起点)async initRootNodes() {this.eventTypeLoading = true;try {const res = await this.$api.getRootEventTypes();this.treeData = res.data;} catch (err) {console.error('加载根节点失败', err);} finally {this.eventTypeLoading = false;}},// 懒加载节点数据async getEventTree(node, resolve) {this.eventTypeLoading = true;try {// 根节点没有id,用空字符串或特定标识const parentId = node.id || '';const res = await this.$api.getChildEventTypes(parentId);// 标记是否为叶子节点(根据实际接口返回判断)const children = res.data.map(item => ({...item,isLeaf: !item.hasChildren // 假设有hasChildren字段标识是否有子节点}));resolve(children);} catch (err) {console.error('加载子节点失败', err);resolve([]); // 出错时返回空数组避免组件报错} finally {this.eventTypeLoading = false;}},// 处理远程搜索async handleRemoteSearch(keyword) {if (!keyword) {// 关键词为空时恢复懒加载模式this.handleClearSearch();return;}this.isSearching = true;this.eventTypeLoading = true;try {// 调用搜索接口,获取匹配的树形结构const res = await this.$api.searchEventTypes(keyword);this.searchResult = res.data;} catch (err) {console.error('搜索事件类型失败', err);this.searchResult = [];} finally {this.eventTypeLoading = false;}},// 清空搜索,恢复懒加载状态handleClearSearch() {this.isSearching = false;this.searchResult = [];// 重新初始化根节点(可选,根据需求决定)this.initRootNodes();}},created() {// 初始化根节点this.initRootNodes();}
};
</script>
关键实现要点
- 状态切换:通过
isSearching
标记区分搜索状态和正常懒加载状态 - 数据源切换:搜索时使用
searchResult
,正常状态使用treeData
- 懒加载控制:搜索时关闭懒加载(
lazy: !isSearching
),避免冲突 - 搜索逻辑:
- 关键词为空时恢复懒加载模式
- 搜索结果需要返回完整的树形结构(包含父子关系)
- 加载状态:统一管理
eventTypeLoading
,避免重复加载提示
后端接口需求
- 懒加载接口:根据父节点ID返回子节点列表(包含是否为叶子节点的标识)
- 搜索接口:根据关键词返回匹配的所有节点,且保持树形结构
这种实现方式既能保持大数据量下的性能(懒加载),又能提供灵活的搜索功能,适合大多数树形选择场景。