用easyui DataGrid编辑树形资料

easyui显示编辑树形资料有TreeGrid元件,但是这个元件的vue版本和react版本没有分页功能。virtual scroll功能也表现不佳。

我用DataGrid来处理。要解决的问题点:

(1)如何显示成树形。即,子节点如何有缩进。

先计算好每个节点的层级level,然后template中设置缩进大小。

html 复制代码
<template v-slot:body="{row,column,rowIndex}">
  <div v-Droppable="{dragEnter:onDDKeyDragEnter,drop:onDDKeyDrop}"
    v-Draggable="{row:row,proxy:$refs.DDKeyDragProxy,revert:true,axis:'v',dragStart:onDDKeyDragStart,dragEnd:onDDKeyDragEnd,drag:onDDKeyDrag}"
      @click="onDDKeyClick">
      <span class='tree-indent' :style='{width:(row.acroStates.level*16).toString()+"px"}'></span>
      <span v-if="row.children && row.children.length>0" :class="getDDKeyExpanderClass(row)" @click="onRowToggle($event,row)"></span>
      <span v-else class='tree-indent'></span>
      <span class='tree-title'>{{row[column.field]}}</span>
  </div>
</template>

(2)如何展开和收拢节点。

展开收拢时,计算好每个节点的isVisual属性,通过DataGrid的filter来显示和隐藏。

javascript 复制代码
expandRowRules:[{
  field:'isVisual',
  op:'equal',
  value:true
}],

......
<DataGrid :filterRules="expandRowRules">
......
toggleRow(row){
  if (row.acroStates.state=='open') row.acroStates.state='closed';
  else row.acroStates.state='open';
  let root=row;
  function scanNodes(parent,children){   
    for(let i=0;i<children.length;i++){
      let node=children[i];
      node.isVisual=root.acroStates.state=='open' && parent.acroStates.state=='open';
      if (node.children) scanNodes(node,node.children);
    }
  }
  if (row.children) scanNodes(row,row.children);
},
......
onRowToggle(e,row){
  //console.log('toggle',e,row);
  //this.finishEditing();
  util_treePlain.toggleRow(row);
  this.$refs.tree.doFilter();
  //取消冒泡,使其不触发cellclick事件
  e.cancelBubble=true;
  e.preventDefault();
  e.stopPropagation();
},

(3)排序时如何保持节点的上下级层级关系。

节点按同级排序,按深度优先扫描树形节点,把节点一个个加入到平面的数组中。

javascript 复制代码
expandTree2Plain(treeRows){
  let rows=[];
  function scanNodes(nodes,level){
    for(let i=0;i<nodes.length;i++){
      let node=nodes[i];
      if (!node.acroStates){
        node.acroStates={
          state:'open'
        }
      }
      node.acroStates.level=level;
      node.acroStates.index=rows.length;
      node.isVisual=node.acroStates.state=='open';
      rows.push(node);
      if (node.children){
        scanNodes(node.children,level+1);
      }
    }
  }
  scanNodes(treeRows,0);
  return rows;
},
sortTree2Plain(treeRows,sorts){
  let rows=[];
  function scanNodes(nodes){
    if (sorts && sorts.length>0){
      nodes.sort(function(a,b){
        let r;
        let v1=a[sorts[0].field];          
        let v2=b[sorts[0].field];
        if (v1==null||v1==undefined) v1='';
        if (v2==null||v2==undefined) v2='';
        if (sorts[0].field=='SortNumber'){
          if (v1=='') v1=-1;else v1=parseInt(v1);
          if (v2=='') v2=-1;v2=parseInt(v2);
        }
        if (v1<v2) r=-1;
        else if (v1==v2) r=0;
        else r=1;
        if (sorts[0].order=='desc') r=-r;
        return r;
      });
    }
    for(let i=0;i<nodes.length;i++){
      let node=nodes[i];
      node.acroStates.index=rows.length;
      rows.push(node);
      if (node.children) scanNodes(node.children);
    }
  }
  scanNodes(treeRows);
  //console.log(rows);
  return rows;
},
相关推荐
IT_陈寒20 分钟前
Java的HashMap竟然不是线程安全的?刚在生产环境踩了坑
前端·人工智能·后端
JarvanMo22 分钟前
再见吧CocoaPods,Swift Package Manager(SPM)即将在Flutter 3.44中成为默认依赖管理器
前端
小则又沐风a29 分钟前
基础的开发工具(2)---Linux
java·linux·前端
yqcoder29 分钟前
JavaScript 事件流:从“捕获”到“冒泡”的完整旅程
服务器·前端·javascript
普修罗双战士39 分钟前
项目设计-文章系统发布文章完整前后端设计
java·数据库·vue.js·spring boot·git·intellij-idea
Csvn40 分钟前
Vue 3 Composition API 深度解析
前端·vue.js
鹏程十八少40 分钟前
11. 2026金三银四 能答对这 29 道题,你的 Android 插件化就算真正通关了
前端·后端·面试
潇凝子潇1 小时前
使用英伟达免费调用多家大模型API
java·前端·javascript
旷世奇才李先生1 小时前
Vue 3\+Vite\+Pinia实战:前端工程化与组件化开发全指南
前端·vue.js
Beginner x_u1 小时前
前端八股整理(手写 01)|Promise 超时控制、红绿灯与 Promise.all
前端·javascript·promise