element-ui 的el-tree控件动态加载更新

element-ui官方文档(官方文档)提供了懒加载自定义叶子节点,主要是通过resolve()来返回。

使用:

  1. 页面上先引入element ui相关js和css.
  2. el-tree基础用法:

在这里插入图片描述

<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>

<script>
  export default {
    data() {
      return {
        data: [{
          label: '一级 1',
          children: [{
            label: '二级 1-1',
            children: [{
              label: '三级 1-1-1'
            }]
          }]
        }, {
          label: '一级 2',
          children: [{
            label: '二级 2-1',
            children: [{
              label: '三级 2-1-1'
            }]
          }, {
            label: '二级 2-2',
            children: [{
              label: '三级 2-2-1'
            }]
          }]
        }, {
          label: '一级 3',
          children: [{
            label: '二级 3-1',
            children: [{
              label: '三级 3-1-1'
            }]
          }, {
            label: '二级 3-2',
            children: [{
              label: '三级 3-2-1'
            }]
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      };
    },
    methods: {
      handleNodeClick(data) {
        console.log(data);
      }
    }
  };
</script>

对于数据不多的情况下可以后台直接组装这种格式返回,但由于我这边的物资编码数据量较大(六千多条),如果全部一次性返回会导致页面渲染时速度缓慢,影响体验。所以这边采用动态加载的方式实现,初始时只查询一级节点,之后每点击一次传此节点的id去查询它下面的节点。

  1. 实际应用

引入el-tree组件:设置相关属性

<!-- 搜索与筛选 -->
    <div class="mysearch">
      <div class="search-header row">
        <div class="col-12 myfrom row">
          <input type="search" placeholder="搜索物资设备服务编码/物资名称" class="col-10" v-model="searchParam">
          <i 
          v-show="circle"
          class="fa fa-times-circle empty"
          @click="oncircle"
          ></i>
          <a href="javascript:;" class="col-3" @click="load()"><i class="iconfont">&#xe7b7;</i>搜索</a>	
        </div>
        <div class="col-3 screen">
          <a href="javascript:;" @click="showPopup(true)"><i class="fa fa-filter"></i>筛选</a>
        </div>
        <van-popup v-model="show" position="right" style="width: 80%;height: 100%;" closeable close-icon="close">
          <li style="padding: 0.3rem 0 0.3rem 0.2rem;">类别筛选</li>
          
          <el-tree
            class="filter-tree"
            :props="lazyProps" //指定节点的label以及子节点的data等
            :load="loadNode" // 点击某节点时会调用该方法,以查询该节点的子节点,同一节点多次点击仅执行(加载)一次
            accordion
            lazy
            @node-click="handleBucketClick"> //点击事件方法
          </el-tree>
        </van-popup>
      </div>
    </div>
  <!-- 搜索与筛选 -->

动态加载节点数据,这里通过 ele 提供的 loadNode() 方法 。

var vm = new Vue({
	el: "#dpLTE",
	data: {
		mescroll : null,
		matMatcode : {},
		searchParam: null, //搜索框内容
		show: false,
		activeNames: ["1"],
		materialCodeList: [],
		materialCodeData:[],
		treeData : [],
		loading: false,
		lazyProps: {
	          children: 'children',
	          label: 'label',
	          isLeaf: 'leaf'
	    },
    circle:false
	},
	mounted : function() {
        this.mescroll = meScrollUtils.init({
            element : 'mescroll',
            callback : function(page) {
  		  		vm.upCallback(page);
  		  	}
  	  	});
    },
	methods: {
		load : function() {
            vm.mescroll.scrollTo(0, 0);      //回到顶层
            vm.mescroll.resetUpScroll(true); //重置列表为第一页
            if (!$('#screenbox').is(':hidden')) { //显示
                $('#screenbox').slideUp();
            }
        },
        searchDiv : function() {
            if ($('#screenbox').is(':hidden')) { //隐藏
                $('#screenbox').slideDown();
            } else {
                $('#screenbox').slideUp();
            }
        },
		
		loadNode : function(node, resolve) {
            //如果展开第一级节点,从后台加载一级节点子列表
            if (node.level == 0) {
                this.getTreeData('00', resolve); // 这里返回的格式为 [{...}]
            }
            if (node.level > 3){
            	return resolve([]);
            }
        
            //如果展开其他级节点,动态从后台加载其下一级节点列表
            if (node.level > 0) {
                setTimeout(() => {
                    this.getTreeData(node, resolve); // 这里返回的是子节点childens集合
                }, 200);
            }
        },
        getTreeData : function(node, resolve) {
        	var orderCodeParent = '00'
        	if(node !='00'){
        		orderCodeParent = node.data.id;
        	}
       		$.get('../../stock/matCatery/findMobileTreeData', {orderCodeParent:orderCodeParent},function(data) {
   				if(node.level == 3){ //判断如果是三级节点,将不再继续展开
		            data.list.forEach(item => {
		              	item.leaf = true;
		            });
   				}
           if(data.list.length == 0){
             data.list = [
               {
                 label: '-- 空 --',
                 children: null,
                 leaf: true,
               }
             ]
           }
   				return resolve(data.list);
   			})
        },
        //当点击的是最末级节点的时候,获取此节点的id赋值给列表对象的属性,再调用load方法来实现过滤查询的功能。
        handleBucketClick : function(data,node){
            if(node.level == 4){
	            vm.matMatcode.matCateryId = data.matCateryId;
	            vm.showPopup(false); //隐藏搜索栏
	            vm.load(); 
            }
       },
        //上拉回调 
        upCallback : function(page) {
            vm.matMatcode.pageNumber = page.num; // 页码, 默认从1开始 
            vm.matMatcode.pageSize = page.size;
            vm.matMatcode.mobile = 1;
            vm.matMatcode.auditStatus = 3;
            vm.matMatcode.sortName = 't.mat_num';
            vm.matMatcode.sortOrder = 'ASC';
            vm.matMatcode.searchParam = vm.searchParam;
            setTimeout(function() {
                $.ajax({
                    type : 'post',
                    url : '../../stock/matMatcode/searchs?_' + $.now(),
                    data : JSON.stringify(vm.matMatcode),
                    dataType : 'json',
                    contentType : 'application/json',
                    success : function(data) {
                        var curPageData = data.rows;
                        var totalPage = data.totalPages;
                        if (page.num == 1) {
                            vm.materialCodeList = [];
                        }
                        vm.mescroll.endByPage(curPageData.length, totalPage);
                        vm.materialCodeList = vm.materialCodeList.concat(curPageData);
                    },
                    error : function(e) {
                        //联网失败的回调,隐藏下拉刷新和上拉加载的状态
                        vm.mescroll.endErr();
                    }
                });

            }, 500)
        },
		
      //右侧筛选栏
      showPopup(flag) {
        this.show = flag;
      },
      //点击清空搜索框
      oncircle:function(){
        this.searchParam = ""
      }
	},
  //监听搜索框文本变化
  watch:{
    "searchParam":function(){
      if(this.searchParam == ""){
        this.circle = false;
        this.load();       //重新加载数据
      }else{
        this.circle = true;
      }
    }
  }
});
  1. 后台方法
@RequestMapping("/findMobileTreeData")
	public Map<String,Object> findMobileTreeData(@RequestParam String orderCodeParent) {
		Map<String, Object> map = new HashMap<>();
		//查询所有数据
		List<MatCatery> listAll = matCateryService.treeListByOrderParentCode(orderCodeParent);
		List<Map<String, Object>> myList = new ArrayList<>();
		//遍历一级分类
		listAll.forEach(mat ->{
			Map<String, Object> mapTemp = new HashMap<>();
			mapTemp.put("matCateryId", mat.getId());
			mapTemp.put("id", mat.getOrderCode());
			mapTemp.put("label", mat.getCateryName());
			mapTemp.put("children", null);
			myList.add(mapTemp);
		});
		map.put("list", myList);
		return map;
	}
  1. 最终效果


版权声明:本文为weixin_43766801原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。