element tree懒加载(自写)

3 篇文章 0 订阅
2 篇文章 0 订阅
  • 需求:树形结构懒加载,一共三层,默认显示第一和第二层,第三层数据通过点击第二次数据层请求接口再显示(主要是第三层数据量大加载太慢,所以分开展示),点击第二次请求数据时该层需要有加载动画就是那个loading图标

  • 接口:一共两个接口,第一个接口返回第一层和第二层数据,第二个接口返回第三层数据(通过点击第二层某个触发,请求参数为当前第二层的id)

  • 环境:vue2,element ui

  • 原理:主要是后端先写完接口了,但是接口不太符合tree自带的懒加载需要的格式,所以前端只能自己写个懒加载,懒加载说到底就是点击了才请求该层数据,所以只要第三层接口可以用就也行,

  • 知识点

    1. 加载动画需要自己添加所以需要使用tree的插槽
    2. 使用tree的方法@node-click,点击层级触发该方法
  • 代码

// html
	<el-tree 
                :data="dataTree"
                :props="defaultProps"
                show-checkbox
                @check-change="handleCheckChange"
                check-strictly
                node-key="id"
                ref="tree"
                :default-expand-all="true"
                @node-click="nodeExpand"
                >
                <template slot-scope="{node,data}">
                    <div>
                        <span v-if="data.iState==1"><i class="el-icon-loading"></i></span>
                        <span >{{data.name}}</span>
                    </div>
                </template>
             </el-tree>

// js
  import { searchParent,searChild} from '@/api/xxxx/tree.js'; // 接口js文件
  	    created(){
       	 this.getList()
    	},
	  	data() {
	        return{
	            treeloading:true,// 树形结构加载
	            dialogVisible:false,
	            searchVal:'',// 搜索值
	            dataTree: [],
	            defaultProps: {
	                children: 'child',
	                label: 'name',
	                id:'id',
	               
	                disabled: function (data, node) {//带子级的节点不能选中
	                   
	                    if (node.level && node.level!==3) {
	                        return true
	                    } else {
	                        return false
	                    }
	                },
	            },
	          
	        } 
	    },
      methods: {
	    /**  */
	    
	    // 
	    getList(){
	        this.treeloading= true
	        searchParent().then(res=>{
	            if(res.code==200){
	                let acce = res.data.map(item=>{
	                    if(item.child){
	                        item.child.forEach(itemChild=>{
	                            itemChild['iState']=false 	// 添加加载动画控制符 true显示,false隐藏,请求值加载,请求成功后隐藏
	                        })
	                        return item
	                    }
	                })
	    
	                this.dataTree = acce
	
	                this.$refs.tree.setCheckedKeys([])
	                this.treeloading = false
	                // this.dialogVisible = true
	            }
	
	        })
	     },
	
	     /** 展开节点 */
	     nodeExpand(obj,node,componentObj){
	        if(node.level==2){
	            if(obj.child.length>0) return // 如果有孩子了就说明刚才已经加载过,就不继续请求接口了
	            /** 点击第二层时请求接口 */
	            obj['iState'] =true
	            searChild(obj.id).then(res=>{
	                if(res.code==200){
	                    obj.iState = false
	                    obj.child = res.data // 这个地方感觉想到的非常棒!目前还没测出bug(把请求的第三层的数据直接加载点击的第二层的对象的孩子下!,利用了vue响应式数据的原理应该)
	                }
	            })
	        }
	     },
	}


  • 效果展示

    • 点击第二层的某一个,请求接口出现加载动画
      请添加图片描述
    • 加载出数据
      请添加图片描述
  • 第一个接口的数据结构模拟 searchParent, 一起返回的是第一层和第二层的数据

    res.data =[
    	 {
    	  "id": 1,
    	  "name": "Group1",
    	  "child": [
    	    {
    	      "id": 128,
    	      "name": "qq",
    	      "child": []
    	    },
    	    {
    	      "id": 129,
    	      "name": "ww",
    	      "child": []
    	    },
    	    {
    	      "id": 130,
    	      "name": "ee",
    	      "child": []
    	    },
    	    {
    	      "id": 131,
    	      "name": "rr",
    	      "child": []
    	    },
    	  ]
    	}
    ]
    
    
  • 第二个接口返回数据格式模拟 searChild,仅仅返回第三层数据

    res.data =[
    	{
    	    "id": 1233,
    	    "name": "cc"
    	},
    	{
    	    "id": 123434,
    	    "name": "ff"
    	},
    ]
    

需求增加:

需求描述:第二层在没点击的情况下需要显示下拉箭头,点击下拉箭头请求第三层数据(默认不知道第二层是否有孩子的情况下是没下拉箭头的,因为这没有使用element自带的懒加载所以isLeaf属性无效,只能从数据方面下手),需要改动的地方有三处

  1. tree的属性方法名由node-click改为node-expand展开是请求数据,把树设置为默认不展开层级

    @node-expand="nodeExpand"
    :default-expand-all="false"
    
  2. 修改第一次请求数据后返回的数据结构,给第二层数据添加假孩子

    getList(){
    	        this.treeloading= true
    	        searchParent().then(res=>{
    	            if(res.code==200){
    	                let acce = res.data.map(item=>{
    	                    if(item.child){
    	                        item.child.forEach(itemChild=>{
    	                            itemChild['iState']=false 	// 添加加载动画控制符 true显示,false隐藏,请求值加载,请求成功后隐藏
    	                            itemChild['child'] = [{name:null}] // 修改处,后续有孩子就替换,无孩子就改为空数组
    	                        })
    	                        return item
    	                    }
    	                })
    	    
    	                this.dataTree = acce
    	
    	                this.$refs.tree.setCheckedKeys([])
    	                this.treeloading = false
    	                // this.dialogVisible = true
    	            }
    	
    	        })
    	     },
    
  3. 修改点击第二层下拉箭头时请求的方法逻辑,看是否有孩子,有孩子就替换,没孩子就把该层child设为【】

    /** 展开节点 */
    	     nodeExpand(obj,node,componentObj){
    	        if(node.level==2){
    	            if(obj.child[0].name!=null) return  // 如果第一个孩子有名称就说明刚才已经加载过,就不继续请求接口了
    	            /** 点击第二层时请求接口 */
    	            obj['iState'] =true
    	             obj['child'] =[]
    	            searChild(obj.id).then(res=>{
    	                if(res.code==200){
    	                    obj.iState = false
    	                    if(res.data.length>0){
                            	obj.child = res.data // 请求接口返回的有孩子才赋值,没孩子就把第二步加的假孩子child设为[],去除假数据
                        	}
    	                }
    	            })
    	        }
    	     },
    
  4. 改后效果:即在第一次请求接口给把第二层增加下拉箭头(无论第二层有没有孩子,后续请求第二层接口时会判断,没孩子就去掉箭头)
    在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值