element ui改写实现两棵树

Posted xuqp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了element ui改写实现两棵树相关的知识,希望对你有一定的参考价值。

使用element ui组件库实现一个table的两棵树的效果

效果如下,左边树自动展开一级,右边树默认显示楼层,然后可以一个个展开

技术图片

 

 

代码如下

 <el-table :data="relativeData"
              :fit="isFit" 
              height="700px"
              :row-style="showTr"   
              :row-class-name="tableRowClassName"  
              :header-row-class-name="tableRowClassName" 
              size="small"
              highlight-current-row>
      <el-table-column fixed   
                       width="310"
                       show-overflow-tooltip
                       style="max-width:310px;">
        <template slot="header">
          <div class="monitor_header">
            <div class="monitor_item">分项名称</div>
            <div class="line_item"></div>
            <div class="building_item">建筑空间</div>
          </div>
        </template>
        <template slot-scope="scope">
          <template v-if="spaceIconShow()">
            <span v-for="(space, levelIndex) in scope.row._level"
                  class="ms-tree-space"
                  :key="levelIndex"></span>
          </template>

          <span class="button"
                v-if="toggleIconShow(scope.row)"
                @click="toggle(scope.$index)">
            <i v-if="!scope.row._expanded"
               class="el-icon-plus"
               aria-hidden="true"></i>
            <i v-if="scope.row._expanded"
               class="el-icon-minus"
               aria-hidden="true"></i>
          </span>
          <span class="ms-tree-space"></span>
          {{scope.row.name}}
          <div class="table_tree_icons">

            <i class="plus_icon"
               @click.stop="addMonitorDailog(scope.row,$event)"></i>
            <i class="edit_icon"
               @click.stop="updateMonitorDailog(scope.row,$event)"></i>
            <i class="delete_icon"
               v-if="scope.row.parentNodeId!=‘0‘"
               @click.stop="
                   deleteMonitor(scope.row,$event)"></i></div>
        </template>
      </el-table-column>
      <el-table-column v-for="(building,index) in spaceTreeData2"
                       :key="index"
                       show-overflow-tooltip
                       :label="building.name">
        <template slot="header">
          <!-- <i class="el-icon-plus"
                   style="color:#ddd;margin-right:5px;cursor:pointer"
                   @click="toggleExpandFloor(building.id,$event)"></i> -->
          <div>{{building.name}}</div>
        </template>
        <el-table-column width="120"
                         show-overflow-tooltip>
          <el-table-column width="120"
                           show-overflow-tooltip>
            <template slot-scope="scope">
              <template v-if="!(scope.row.relatives.some(item => {if(item.spaceId==building.id){return true;}}))">
                <span class="row-column-express"
                      @click.stop="addExpress(scope.row,building.id,$event)">--</span>
              </template>
              <template v-for=" (item,index) in scope.row.relatives">
                <span class="row-column-express"
                      :key="index"
                      v-if="item.spaceId==building.id"
                      @click.stop="updateExpress(item,$event)">{{ item.expression }}</span>
              </template>
            </template>
          </el-table-column>
        </el-table-column>
        <template v-if="showFloor &&building.children&& building.children.length>0">
          <!--  :render-header="renderHeaderSecond" -->
          <el-table-column v-for="(floor,findex) in building.children"
                           :key="findex"
                           show-overflow-tooltip
                           :label="floor.name"
                           width="120">
            <template slot="header"
                      slot-scope="scope">
              <div><i class="el-icon-plus"
                   @click="expandFloorInfo(scope,floor,$event)"></i><span>{{floor.name}}</span></div>
            </template>
            <el-table-column width="120"
                             show-overflow-tooltip>
              <template slot-scope="scope">
                <template v-if="!(scope.row.relatives.some(item => {if(item.spaceId==floor.id){return true;}}))">
                  <span class="row-column-express"
                        @click.stop="addExpress(scope.row,floor.id,$event)">--</span>
                </template>
                <template v-for=" (item,index3) in scope.row.relatives">
                  <span class="row-column-express"
                        :key="index3"
                        v-if="item.spaceId==floor.id"
                        @click.stop="updateExpress(item,$event)">{{ item.expression }}</span>
                </template>

              </template>
            </el-table-column>
            <template v-if="floor.children && floor.children.length>0">
              <el-table-column v-for="(room,index2) in floor.children"
                               show-overflow-tooltip
                               :key="index2"
                               :label="room.name"
                               width="120">
                <template slot-scope="scope">
                  <template v-if="!(scope.row.relatives.some(item => {if(item.spaceId==room.id){return true;}}))">
                    <span class="row-column-express"
                          @click.stop="addExpress(scope.row,room.id,$event)">--</span>
                  </template>
                  <template v-for=" (item,index4) in scope.row.relatives">
                    <span class="row-column-express"
                          :key="index4"
                          v-if="item.spaceId==room.id"
                          @click.stop="updateExpress(item,$event)">{{ item.expression }}</span>
                  </template>

                </template>
              </el-table-column>

            </template>
          </el-table-column>
        </template>
      </el-table-column>
    </el-table>

数据层

  props: {
    //左边分项树的内容
    monitorRelativeData: {
      type: Array
    },
   //头部空间树的数据
    spaceTreeData: {
      type: Array
    }
  }, 
data() {
    return {
      expandRowKeys: [], //默认展开的节点
      isFit: false, //table是否自适应
      roomList: []//为了控制房间的显示,存储房间集合
    }
  },  
computed: {
    //数据的处理,每条数据是否展开,父节点信息等
    relativeData() {
      let data = MSDataTransfer.treeToArray(this.monitorRelativeData, null, null, true)
      return data
    },
    //只存储楼层,房间另外存储
    spaceTreeData2() {
      var res = this.spaceTreeData
      var roomList = []
      if (res.length == 0 || !res[0].children) {
        return []
      }
      res[0].children = this.spaceTreeData[0].children.map(function(item) {
        item.len = item.children ? item.children.length : 0
        if (item.len > 0) {
          roomList = roomList.concat(item.children)
        }
        item.children = []
        return item
      })
      this.roomList = roomList
      return res
    },
    buildingId() {
      return this.$store.getters.buildingId
    }
  },  
            
MSDataTransfer.treeToArray是把tree的层级关系进行处理  加入 _expanded属性,_parent父节点属性,_level层级关系
// 数据转换
DataTransfer.treeToArray = function(data, parent, level, expandedAll) {
  let tmp = [];
  Array.from(data).forEach(function(record) {
    if (record._expanded === undefined) {
      Vue.set(record, "_expanded", expandedAll);
    }
    if (parent) {
      Vue.set(record, "_parent", parent);
    }
    let _level = 0;
    if (level !== undefined && level !== null) {
      _level = level + 1;
    }
    Vue.set(record, "_level", _level);
    tmp.push(record);
    if (record.children && record.children.length > 0) {
      let children = DataTransfer.treeToArray(
        record.children,
        record,
        _level,
        expandedAll
      );
      tmp = tmp.concat(children);
    }
  });

  return tmp;
};
MSDataTransfer.treeToArray处理左边树的时候是,默认展开所有,然后在每次操作的时候,都对树的是否展开状态进行更改

 

 updated() {
    this.toggleAll()
  },
  methods: {
    //test add
    spaceIconShow(index) {
      return true
    },
    toggleIconShow(record) {
      if (record.children && record.children.length > 0) {
        return true
      }
      return false
    },
    toggle(trIndex) {
      let record = this.relativeData[trIndex]
      record._expanded = !record._expanded
      //展开的数据节点
      if (record._expanded) {
        this.expandRowKeys.push(record.id)
      } else {
        var expandRowKeys = []
        this.expandRowKeys.forEach(function(item) {
          if (item != record.id) {
            expandRowKeys.push(item)
          }
        })
        this.expandRowKeys = expandRowKeys
      }
    },
    showTr(rows, index) {
      let row = rows.row
      let show = row._parent ? row._parent._expanded && row._parent._show : true
      row._show = show
      return show ? ‘‘ : display:none;
    },
    toggleAll() {
      /**
       * i 从1开始,不收起第一级节点
       */
      for (let i = 1; i < this.relativeData.length; i++) {
        let record = this.relativeData[i]
        if (this.expandRowKeys.indexOf(record.id) == -1) {
          record._expanded = false
        }
      }
      console.log(toggleAll, this.relativeData)
    },/**关闭房间 */
    expandFloorInfo(row, floor, event) {
      if (floor.len > 0 && floor.children.length == 0) {
        var roomList = this.roomList
        for (var i = 0; i < roomList.length; i++) {
          if (roomList[i].parentNodeId && roomList[i].parentNodeId == floor.nodeId) {
            floor.children.push(roomList[i])
            if (floor.len == floor.children.length) {
              break
            }
          }
        }
        this.expandFloorInfo(row, floor, event)
        return
      }
      var column = row.column
      console.log(column, column)
      var len = floor.children.length
      var columnArr = column.id.split(_)
      var num = columnArr[columnArr.length - 1]
      columnArr.pop()
      columnArr.pop()
      var tableClass = columnArr.join(_)
      console.log(tableClass, tableClass)
      num++
      //展开
      if (event.target.className == el-icon-plus) {
        event.target.className = el-icon-minus
        event.target.parentNode.parentNode.parentNode.colSpan = len + 1
        JQuery(. + tableClass)[0].colSpan += len
        JQuery(.el-table table.el-table__header).css(cssText, width:310px !important)
        JQuery(.el-table table.el-table__body).css(cssText, width:310px!important)
        JQuery([name^= + column.id + _]).show()
        JQuery([class^= + column.id + _]).show()
      } else {
        //收缩
        event.target.className = el-icon-plus
        JQuery([name^= + column.id + _]).hide()
        JQuery([class^= + column.id + _]).hide()
        JQuery([name^= + column.id + _column_ + num + ]).show()
        JQuery([class^= + column.id + _column_ + num + ]).show()
        event.target.parentNode.parentNode.parentNode.colSpan = 1
        JQuery(. + tableClass)[0].colSpan -= len
        JQuery(.el-table table.el-table__body).css(cssText, width:310px !important)
        JQuery(.el-table table.el-table__header).css(cssText, width:310px !important)
      }
    },
}

 

以上是关于element ui改写实现两棵树的主要内容,如果未能解决你的问题,请参考以下文章

学 Flutter 不理解 Widget/Element/Render 三棵树?啥也不是!

PAT-树的同构

一条公路西边植树两棵树相距3.45米51棵树之间的距离是多少米?

二叉树oj ----> 判断两棵树是否相同

LeetCode-两棵二叉搜索树的所有元素

检查两棵树是不是相同