vue+element UI实现树形表格带复选框的示例代码

一:在component文件夹下新建如下treeTable文件夹,里面有2个文件:

eval.js:将数据转换成树形数据

/**
 * @Author: jianglei
 * @Date: 2017-10-12 12:06:49
 */
"use strict";
import Vue from "vue";
export default function treeToArray(
 data,
 expandAll,
 parent = null,
 level = null
) {
 let tmp = [];
 Array.from(data).forEach(function(record) {
 if (record._expanded === undefined) {
  Vue.set(record, "_expanded", expandAll);
 }
 let _level = 1;
 if (level !== undefined && level !== null) {
  _level = level + 1;
 }
 Vue.set(record, "_level", _level);
 // 如果有父元素
 if (parent) {
  Vue.set(record, "parent", parent);
 }
 tmp.push(record);
 if (record.child && record.child.length > 0) {
  const child = treeToArray(record.child, expandAll, record, _level);
  tmp = tmp.concat(child);
 }
 });
 return tmp;
}

index.vue:树形表格组件

<template>
 <el-table ref="multipleTable" :data="formatData" :row-style="showRow" v-bind="$attrs"> <!-- @header-click="chooseall" -->
 <el-table-column :render-header="renderHeader" width="50" align="center">
  <template slot-scope="scope">
  <el-checkbox v-model="scope.row.checks" @change="toselect(scope.row)"></el-checkbox>
  </template>
 </el-table-column>
 <el-table-column v-if="columns.length===0" width="150">
  <template slot-scope="scope">
  <span v-for="space in scope.row._level" :key="space" class="ms-tree-space"/>
  <span v-if="iconShow(0,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
   <i v-if="!scope.row._expanded" class="el-icon-plus"/>
   <i v-else class="el-icon-minus"/>
  </span>
  {{ scope.$index }}
  </template>
 </el-table-column>
 <el-table-column v-for="(column, index) in columns" v-else :key="column.value" :label="column.text" :width="column.width">
  <template slot-scope="scope">
  <!-- Todo -->
  <!-- eslint-disable-next-line vue/no-confusing-v-for-v-if -->
  <span v-for="space in scope.row._level" v-if="index === 0" :key="space" class="ms-tree-space"/>
  <span v-if="iconShow(index,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
   <i v-if="!scope.row._expanded" class="el-icon-plus"/>
   <i v-else class="el-icon-minus"/>
  </span>
  {{ scope.row[column.value] }}
  </template>
 </el-table-column>
 <slot/>
 </el-table>
</template>

<script>
/**
 Auth: Lei.j1ang
 Created: 2018/1/19-13:59
*/
import treeToArray from "./eval";
export default {
 name: "TreeTable",
 data() {
 return {
  chooseson: true, //全选
  key: true //单个点击直到全部选中
 };
 },
 props: {
 /* eslint-disable */
 data: {
  type: [Array, Object],
  required: true
 },
 columns: {
  type: Array,
  default: () => []
 },
 evalFunc: Function,
 evalArgs: Array,
 expandAll: {
  type: Boolean,
  default: false
 }
 },
 computed: {
 // 格式化数据源
 formatData: function() {
  let tmp;
  if (!Array.isArray(this.data)) {
  tmp = [this.data];
  } else {
  tmp = this.data;
  }
  const func = this.evalFunc || treeToArray;
  const args = this.evalArgs
  ? [tmp, this.expandAll].concat(this.evalArgs)
  : [tmp, this.expandAll];
  return func.apply(null, args);
 }
 },
 methods: {
 showRow: function(row) {
  const show = row.row.parent
  ? row.row.parent._expanded && row.row.parent._show
  : true;
  row.row._show = show;
  return show
  ? "animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;"
  : "display:none;";
 },
 // 切换下级是否展开
 toggleExpanded: function(trIndex) {
  const record = this.formatData[trIndex];
  record._expanded = !record._expanded;
 },
 // 图标显示
 iconShow(index, record) {
  return index === 0 && record.child && record.child.length > 0;
 },

 //设置表头全选
 renderHeader(h, data) {
  return h("span", [
  h("input", {
   attrs: {
   id: "chooseall",
   type: "checkbox",
   style:
    "border: 1px solid #dcdfe6;border-radius: 2px;box-sizing: border-box;width: 14px;height: 14px;background-color: #fff;"
   }
  })
  ]);
 },
 //功能函数:选中部分子集
 setchildtobeselect(arr, key) {
  arr.forEach((v, i) => {
  v.checks = key;
  // v._expanded = key;//选中后展开子项
  if (v.child) {
   this.setchildtobeselect(v.child, v.checks);
  }
  });
 },
 //是否所有的都被选中
 isallchecked(arr) {
  arr.forEach((v, i) => {
  if (!v.checks) {
   this.key = false;
  }
  if (v.child) {
   this.isallchecked(v.child);
  }
  });
 },
 //设置父级为 未选中状态(父级的父级没改变-有bug)
 setparentfalse(arr, id, level) {
  arr.forEach((v, i) => {
  if (v._level == level - 1 && v.child) {
   v.child.forEach((val, ind) => {
   if (val.id == id) {
    v.checks = false;
    return false; //终止此次循环,减少循环次数
   }
   });
  }
  if (v.child) {
   this.setparentfalse(v.child, id, level);
  }
  });
 },
 //设置父级为 选中状态
 setparenttrue(arr, id, level) {
  arr.forEach((v, i) => {
  if (v._level == level - 1 && v.child) {
   let key = true;
   let sameidkey = false;
   v.child.forEach((val, ind) => {
   if (val.id == id) {
    //确保当前点击的在该父级内
    sameidkey = true;
   }
   if (!val.checks) {
    key = false;
   }
   });
   if (key && sameidkey) {
   v.checks = true;
   }
  }
  if (v.child) {
   this.setparentfalse(v.child, id, level);
  }
  });
 },
 //某个复选框被点击时
 toselect(row) {
  console.log(row);
  // row._expanded = row.checks;//选中后是否展开
  //1、若有子集先让子选中
  if (row.child) {
  this.setchildtobeselect(row.child, row.checks);
  }
  //2、然后判断是否全选中
  this.key = true; //重置为true,防止上次已经是false的状态
  this.isallchecked(this.formatData);
  //3、设置多选框的状态
  if (!row.checks) {
  this.setparentfalse(this.formatData, row.id, row._level); //设置父级选中的状态为false
  document.getElementById("chooseall").checked = false; //设置全选框的状态
  } else {
  this.setparenttrue(this.formatData, row.id, row._level); //设置父级选中的状态为true
  }
  if (this.key) {
  document.getElementById("chooseall").checked = true; //设置全选框的状态
  }
 }
 },
 mounted() {
 this.$nextTick(() => {
  var that = this;
  const all = document.getElementById("chooseall");
  all.onchange = function(e) {
  console.log(all.checked);
  if (all.checked == true) {
   that.setchildtobeselect(that.formatData, true);
  } else {
   that.setchildtobeselect(that.formatData, false);
  }
  };
 });
 }
};
</script>
<style rel="stylesheet/css">
@keyframes treeTableShow {
 from {
 opacity: 0;
 }
 to {
 opacity: 1;
 }
}
@-webkit-keyframes treeTableShow {
 from {
 opacity: 0;
 }
 to {
 opacity: 1;
 }
}
</style>

<style scoped>
.ms-tree-space {
 position: relative;
 top: 1px;
 display: inline-block;
 font-style: normal;
 font-weight: 400;
 line-height: 1;
 width: 18px;
 height: 14px;
}
.ms-tree-space::before {
 content: "";
}
.processContainer {
 width: 100%;
 height: 100%;
}
table td {
 line-height: 26px;
}
.tree-ctrl {
 position: relative;
 cursor: pointer;
 color: #2196f3;
 margin-left: -18px;
}
</style>

二:在需要的地方引入该组件:

例如:在component文件夹下新建a.vue:

<tree-table :data="data" :columns="columns" border/>
import treeTable from "./TreeTable";
components: { treeTable },
data() {
 return {
  columns: [
  {
   text: "事件",
   value: "event",
   width: 200
  },
  {
   text: "ID",
   value: "id"
  }
  ],
  data: [
  {
   id: 0,
   event: "事件1",
   timeLine: 50,
   comment: "无"
  },
  {
   id: 1,
   event: "事件1",
   timeLine: 100,
   comment: "无",
   children: [
   {
    id: 2,
    event: "事件2",
    timeLine: 10,
    comment: "无"
   },
   {
    id: 3,
    event: "事件3",
    timeLine: 90,
    comment: "无",
    children: [
    {
     id: 4,
     event: "事件4",
     timeLine: 5,
     comment: "无"
    },
    {
     id: 5,
     event: "事件5",
     timeLine: 10,
     comment: "无"
    },
    {
     id: 6,
     event: "事件6",
     timeLine: 75,
     comment: "无",
     children: [
     {
      id: 7,
      event: "事件7",
      timeLine: 50,
      comment: "无",
      children: [
      {
       id: 71,
       event: "事件71",
       timeLine: 25,
       comment: "xx"
      },
      {
       id: 72,
       event: "事件72",
       timeLine: 5,
       comment: "xx"
      },
      {
       id: 73,
       event: "事件73",
       timeLine: 20,
       comment: "xx"
      }
      ]
     },
     {
      id: 8,
      event: "事件8",
      timeLine: 25,
      comment: "无"
     }
     ]
    }
    ]
   }
   ]
  }
  ]
 };
 },

最终效果:

这样就大工告成了,想要了解更多,可以关注 vue-element-admin,一个很不错的后台管理模版

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 优雅的将ElementUI表格变身成树形表格的方法步骤

    由于ElementUI目前还未开发树形表格组件,也参阅了网络上部分基于ElementUI表格封装的开源树形组件,如果想进行二次开发的话都不太理想,所以就萌生了自行开发树形表格. 本示例提供开发思路,移除了多余的样式,比较适合新手入门学习,如果应用于实际项目还请自行封装. 目前还仅仅实现了视觉的树结构的层级效果和控制结构的显示隐藏,后续还会进行不断的完善和优化,有必要的话会对组件进行二次封装,有点在重复造论的感觉哈. 效果图 完整代码 页面(tree-table.vue) <template>

  • vue基于element-ui的三级CheckBox复选框功能的实现代码

    最近vue项目需要用到三级CheckBox复选框,需要实现全选反选不确定三种状态.但是element-ui table只支持多选行,并不能支持三级及以上的多选,下面通过本文给大家讲解实现方法. 效果图预览: 首先是页面布局,当然也可已使用table,但是自己用flex布局后面更容易增删改查其他功能 <div class="deliverySetting-table"> <div class="table-head"> <div clas

  • vue+element UI实现树形表格带复选框的示例代码

    一:在component文件夹下新建如下treeTable文件夹,里面有2个文件: eval.js:将数据转换成树形数据 /** * @Author: jianglei * @Date: 2017-10-12 12:06:49 */ "use strict"; import Vue from "vue"; export default function treeToArray( data, expandAll, parent = null, level = null

  • vue+element UI实现树形表格

    本文实例为大家分享了vue+element UI实现树形表格的具体代码,供大家参考,具体内容如下 一.在component文件夹下新建如下treeTable文件夹,里面有2个文件: eval.js:将数据转换成树形数据 /** * @Author: jianglei * @Date: 2017-10-12 12:06:49 */ 'use strict' import Vue from 'vue' export default function treeToArray(data, expandA

  • bootstrap treeview 树形菜单带复选框及级联选择功能

    具体代码如下所示: <div id="searchTree"></div> <script> var treeData = [{ text: "Parent 1", nodes: [{ text: "Child 1", nodes: [{ text: "Grandchild 1" }, { text: "Grandchild 2", nodes: [{ text: &qu

  • vue实现带复选框的树形菜单

    本文实例为大家分享了vue实现带复选框的树形菜单展示的具体代码,供大家参考,具体内容如下 代码: <template> <div id="checkTree"> <div class="tree-box"> <div class="zTreeDemoBackground left"> <ul id="treeDemo" class="ztree">

  • Vue+Element ui实现树形控件右键菜单

    本文实例为大家分享了Vue+Element ui实现树形控件右键菜单的具体代码,供大家参考,具体内容如下 需求 实现树形控件右键菜单功能,有添加文件.删除文件.重命名功能 一.按需引入ELEMENTUI组件 按需引入ELEMENTUI组件 二.实现菜单功能 1.TEMPLATE 代码如下(示例): <!-- 树形组件 -->   <el-tree               :data="data"               @node-contextmenu=&q

  • jquery实现带复选框的表格行选中删除时高亮显示

    通过jquery技术来操作表格是件简单的事,通过jquery的语法,可以很轻松的完成表格的隔行换色,悬浮高亮,在实际的应用中可能会出现表格中带复选框的,删除时,将复选框所在的行的记录删除.在这的地方,可以加个特效,单击某行的同时将该行的复选框选中,该行的背景色也高亮显示.这样给人的感觉非常好. 效果如下:  我做的这里有两个功能: 功能1.单击某行,该行的复选框被选中,同时改变一下背景色. 功能2.单击全选/全不选标签后,改变行的颜色. 两个功能我封装到了js文件中,使用的时候引入就行了. 先看

  • Android TreeView实现带复选框树形组织结构

    之前做项目的时候做人员组织架构时候需要用到,同样可以用于目录视图.简单搜了一下没有合适的,只找到一个基础的有瑕疵的树形结构,就在基础上改了增加了复选框以及简化了部分代码.下面上演示效果图,时长25秒,手机卡见谅. 复选框有两种设计模式: 1.子节点选中则父节点选中,适合多级多item下方便了解哪些被选中: 2.子节点全部选中父节点才选中,更符合日常逻辑,适合少数量以及少层级. 下面上主要代码: 首先上MainActivity,主要作用上加载layout以及读取数据.实际中一般从数据库获取.命名较

  • Java带复选框的树(Java CheckBox Tree)实现和应用

    在使用Java Swing开发UI程序时,很有可能会遇到使用带复选框的树的需求,但是Java Swing并没有提供这个组件,因此如果你有这个需求,你就得自己动手实现带复选框的树. CheckBoxTree与JTree在两个层面上存在差异: 1.在模型层上,CheckBoxTree的每个结点需要一个成员来保存其是否被选中,但是JTree的结点则不需要. 2.在视图层上,CheckBoxTree的每个结点比JTree的结点多显示一个复选框. 既然存在两个差异,那么只要我们把这两个差异部分通过自己的实

  • js+csss实现的一个带复选框的下拉框

    效果图: css: <style type="text/css"> /* 带复选框的下拉框 */ ul li{ list-style: none; padding:0px; margin: 0px; } .select_checkBox{ border:0px solid red; position: relative; display:inline-block; } .chartQuota{ height:23px; float:left; display:inline-

  • layui表格数据复选框回显设置方法

    layui2.3版本,本身并不带有复选框回显功能,那么需要从源头解决此事,F12代码调试,找到与复选框关联的地方发现: 我们只需要在渲染数据回调时找到每个复选框根据数据的不同来设置回显. layui这里有一个坑,设置class属性后会造成二次点击效果,千万不要手动修改class属性,那么应该怎么办呢? 每次**点击**其中一个复选框时都会增加一个class属性,第二次点击又会给删除: table.render({ elem: '#LAY_table_topic', url: '/admin/to

随机推荐