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


Posted in Javascript onApril 16, 2019

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

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

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 UI实现树形表格带复选框的示例代码

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

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

Javascript 相关文章推荐
List Installed Software Features
Jun 11 Javascript
jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
Apr 25 Javascript
js获取判断上传文件后缀名的示例代码
Feb 19 Javascript
js事件监听机制(事件捕获)总结
Aug 08 Javascript
用Move.js配合创建CSS3动画的入门指引
Jul 22 Javascript
jquery实现Li滚动时滚动条自动添加样式的方法
Aug 10 Javascript
JS自定义函数对web前端上传的文件进行类型大小判断
Oct 19 Javascript
JS实现的杨辉三角【帕斯卡三角形】算法示例
Feb 26 Javascript
微信小程序基于Taro的分享图片功能实践详解
Jul 12 Javascript
Vue如何提升首屏加载速度实例解析
Jun 25 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
Jul 26 Javascript
解决Vue大括号字符换行踩的坑
Nov 09 Javascript
JS实现根据详细地址获取经纬度功能示例
Apr 16 #Javascript
Vue 理解之白话 getter/setter详解
Apr 16 #Javascript
在vue中使用setInterval的方法示例
Apr 16 #Javascript
vue实现局部刷新的实现示例
Apr 16 #Javascript
如何自动化部署项目?折腾服务器之旅~
Apr 16 #Javascript
每周一练 之 数据结构与算法(Stack)
Apr 16 #Javascript
在vue中获取微信支付code及code被占用问题的解决方法
Apr 16 #Javascript
You might like
php输出echo、print、print_r、printf、sprintf、var_dump的区别比较
2013/06/21 PHP
php switch语句多个值匹配同一代码块的实现
2014/03/03 PHP
PHP中读取照片exif信息的方法
2014/08/20 PHP
php使用memcoder将视频转成mp4格式的方法
2015/03/12 PHP
php版阿里大于(阿里大鱼)短信发送实例详解
2016/11/30 PHP
Javascript下IE与Firefox下的差异兼容写法总结
2010/06/18 Javascript
理解Javascript_06_理解对象的创建过程
2010/10/15 Javascript
Node.js生成HttpStatusCode辅助类发布到npm
2013/04/09 Javascript
jquery与js函数冲突的两种解决方法
2013/09/09 Javascript
jquery定时滑出可最小化的底部提示层特效代码
2013/10/02 Javascript
JS图片无缝、平滑滚动代码
2014/03/11 Javascript
node.js中使用q.js实现api的promise化
2014/09/17 Javascript
js/jquery判断浏览器类型的方法小结
2015/05/12 Javascript
javascript实现对表格元素进行排序操作
2015/11/18 Javascript
JavaScript兼容性总结之获取非行间样式案例
2016/08/07 Javascript
jQuery中 $ 符号的冲突问题及解决方案
2016/11/04 Javascript
js实现做通讯录的索引滑动显示效果和滑动显示锚点效果
2017/02/18 Javascript
ReactNative踩坑之配置调试端口的解决方法
2017/07/28 Javascript
自定义vue组件发布到npm的方法
2018/05/09 Javascript
Vuex实现数据共享的方法
2019/12/20 Javascript
vue中 v-for循环的用法详解
2020/02/19 Javascript
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
详解Python核心编程中的浅拷贝与深拷贝
2018/01/07 Python
Python多线程模块Threading用法示例小结
2019/11/09 Python
python中元组的用法整理
2020/06/15 Python
python开发一款翻译工具
2020/10/10 Python
英国豪华真皮和布艺沙发销售网站:Darlings of Chelsea
2018/01/05 全球购物
德国最新街头服饰网上商店:BODYCHECK
2019/09/15 全球购物
Happy Plugs官网:瑞典无线耳机品牌
2020/07/16 全球购物
服装销售人员求职自我评价
2013/09/26 职场文书
校长岗位职责
2013/11/26 职场文书
资金主管岗位职责范本
2014/03/04 职场文书
写求职信要注意什么问题
2014/04/12 职场文书
《沙漠中的绿洲》教学反思
2014/04/24 职场文书
查摆剖析材料范文
2014/09/30 职场文书
go:垃圾回收GC触发条件详解
2021/04/24 Golang