基于element-ui树目录的懒加载使用方式

本文档详细介绍了如何使用 Vue.js 的 el-tree 组件实现一个懒加载目录树,其中节点数据由接口动态获取。文章通过代码示例展示了如何配置 props 和 loadNode 方法来处理数据映射和懒加载,并解释了节点展开、点击事件的处理,以及父子组件间的通信。同时,提供了假数据和实际接口调用的示例,帮助开发者快速理解和复现该功能。
摘要由CSDN通过智能技术生成

最近遇见一个需求,生成目录树,奈何只有第一层数据是固定的,所有的子目录都要通过懒加载的方式获取,点击按钮的时候调取接口获取下级目录,故此写个demo记录下,下次懒得再看一遍文档了

懒加载功能事件主要是通过 :load=“loadNode” 方法实现的
第二个主要方法 :props=“props” 是用作数据映射

映射的是当前目录树绑定的数组键值名称,例如:
官方使用的绑定数据是:

[{
          id: 1,
          label: '一级 1',
          children:[]
}]

我们本地的数据是:

[{
            "id": "1001",  
            "type": null,
            "nodeName": "指标",
            "next":[{
                "id": "1001"
            }]
}]

这个时候

  • nodeName 对应为 label
  • next 对应为 children

故此可以用 :props=“props”
props的值为:

data() {
        return {
            data: [],
            props: {
                children: 'next',
                label: 'nodeName'
            },
        }
    },

现在直接放代码,一些相关事件记录在代码下面:

lazyTree.vue 页面

注意: 当前树是写成子组件的方式,在父组件中引入使用的

<template>
<div class="tree_wrap">
        <!-- 指标树 -->
        <el-tree 
	        ref="tree"
	        :props="defaultProps"
	        @node-expand="handlerOpen"
	        node-key="id"
	        :default-expanded-keys="titleIndex"
	        @node-click="handleNodeClick"
	        :highlight-current="showTree"
	        lazy
	        :load="loadNode"
        >
            <span class="custom-tree-node" slot-scope="{ data }">
                <span>
                   	<i :class="data.icon" v-if="data.icon" style="font-size:16px;"></i>
                    {{ data.nodeName }}
                </span>
            </span>
        </el-tree>
    </div>

</template>
<script>
//  这个是获取子目录的接口
import { searchChildern} from '@/network/daptDataUrl'
// 第一层假数据  第一层数据值为固定值  无需懒加载
import treeData from './tree.json'
export default {
    props:{
        // 默认展开的分类id
        titleIndex: {
            type: Array,
            default: []
        }
    },
    data() {
        return {
        	// 数据映射
            defaultProps: {
                children: 'next',
                label: 'nodeName'
            },
            cheackId:'', // 当前选中的目录id
            showTree:true,  // 是否高亮当前选中节点
            childerList:[],// 子目录
            
        }
    },
    created(){
        console.log('父组件传过来的节点:',this.titleIndex)
        // titleIndex 是默认展开目录的 id集合数组  
        // cheackId  是代表当前选中的目录id
        this.cheackId = this.titleIndex[0]
    },
    mounted(){
        this.getCurrentKey()
    },
    methods: {
        handlerOpen(data) {
            // console.log("展开操作",data);
            this.cheackId = data.id
        },
        //跳转当前页面后  设置默认展开和选中的目录
        getCurrentKey(){
            let key = ''
            if(this.titleIndex.length == 1){
                key = this.titleIndex[0];
            }else{
                key = this.titleIndex[1];
            }
            console.log('key:',key)
           this.$nextTick(function(){
	            //通过 key 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性
	            this.$refs.tree.setCurrentKey(key);
            }) 
            this.cheackId = this.titleIndex[0]

        },
        // 点击节点事件
        handleNodeClick(data, node) {//指标
            this.$nextTick(()=>{
                // 若为 null 则取消当前高亮的节点
                this.$refs.tree.setCurrentKey(null)
            })
            this.getResouce(data,node)
        },
        // tree组件向父组件通讯
        getResouce(data,node){
            try {
                console.log("点击事件",'data:',data,"node",node);
                this.cheackId = data.id
                // 这个事件是传递给父组件  告诉父组件点击了当前目录  可以在父组件做其他的数据操作
                this.$emit('get-detail',data)
       
            } catch (error) {
                console.log("await函数报错!");
            }
        },
        // 懒加载下级数据
        loadNode(node, resolve) {
            // console.log("懒加载子目录",node,treeData);
			
			// 层级为零时 返回写死的父目录  也可以都通过接口请求
            if (node.level === 0) {
                // console.log("node.level",node.level);
                // treeData 是json文件中的数据 放在下面
                return resolve(treeData.firstLever);
            }
            // 层级为一时 返回写死的二级目录  
            if (node.level === 1) {
                // console.log("node.level",node.level,treeData);
                    return resolve(treeData.targetsecondLever);
            }
            //当层级大于1时 使用接口获取子目录    使用resolve回调函数返回子目录数据
            if (node.level > 1) {
                this.getNextNode(node.data,resolve)
            }
            // return resolve([]);
        },
        getNextNode(nodeData,resolve){
            // 这里是子级目录的 接口请求操作
            let params = {
                type:"",//类型 
                parentNodeCode: "",//父级节点编码
            }
            console.log("请求子节点入参",nodeData,params);
                
            searchChildern(params).then((response)=>{
                console.log("子节点数组",response.data);
                let res = response.data
                if (res.status == 1) {
                    this.childerList = res.data
                    resolve(res.data)
                } else {
                    console.log("子节点获取失败!!");
                    this.childerList = []
                }
            }).catch((err)=>{
                console.log("子节点获取失败!!");
            })
        }
       
    }
}

</script>

tree.json 假数据

{
    "firstLever":[
        {
            "id": "1001",  
            "type": null,
            "nodeName": "指标",
            "next":[{
                "id": "1001"
            }]
        }
    ],
    "targetsecondLever":[{
            "id": "-1",
            "type": "1",
            "nodeName": "公司体系",
            "next": [{}]
          }, {
            "id": "-2",
            "type": "2",
            "nodeName": "外部体系",
            "next": [{}]
          }, {
            "id": "-3",
            "type": "3",
            "nodeName": "专题体系",
            "next": [{}]
          },
          {
            "id": "-4",
            "type": "4",
            "nodeName": "台区体系",
            "next": [{}]
          }
    ]
}

父组件调用 Index.vue 页面

<template>
	<div class="treeSwich">
        <LazySidebar  :titleIndex="titleIndex" @get-detail="clickAside"></LazySidebar>
    </div>
</template>
<script>
import LazySidebar from './lazyTree.vue';
export default {
  data() {
    return {}
  },
  methods: {
  	// 点击侧边栏 请求资源 
   	clickAside(data){
   		console.log('侧边栏数据:', data)
	}
  }
}
</script>
相关事件:
  1. 节点被展开时触发的事件:

    @node-expand="handlerOpen" 
    
  2. 默认勾选的节点的 key 的数组 titleIndex是个数组
    :default-expanded-keys=“titleIndex”

  3. 节点被点击时的回调
    @node-click=“handleNodeClick”
    节点被点击之后要先清除上一次高亮的目录节点,然后再调取获取子目录数据的接口

  4. 点击子组件后 父组件需要进行的相关操作,通过父子组件通讯实现
    this.getResouce() 函数中this,$emit()事件通知了父组件节点已经被点击,可以请求相关数据了

tip:

如果目录树需要展示相关图表,可以在绑定数据中新增icon字段,放置相关icon值,即可渲染

在这里插入图片描述

实例数据:

"firstLever":[
        {
            "id": "1001",  
            "type": null,
            "nodeName": "指标",
            "icon": "el-icon-s-tools",
            "next":[{
                "id": "10010"
            }]
        }
    ],

哦了 总结完毕~~~
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值