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 相关文章推荐
C#中TrimStart,TrimEnd,Trim在javascript上的实现
Jan 17 Javascript
jQuery的deferred对象使用详解
Aug 20 Javascript
range 标准化之获取
Aug 28 Javascript
js实现单一html页面两套css切换代码
Apr 11 Javascript
jquery实现在页面加载的时自动为日期插件添加当前日期
Aug 20 Javascript
基于jquery实现下拉框美化特效
Feb 02 Javascript
JavaScript实现点击文本自动定位到下拉框选中操作
Jun 15 Javascript
jQuery树形控件zTree使用小结
Aug 02 Javascript
纯js实现动态时间显示
Sep 07 Javascript
vue如何根据网站路由判断页面主题色详解
Nov 02 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
Oct 27 Javascript
vue route新窗口跳转页面并且携带与接收参数
Apr 10 Vue.js
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正则表达式使用的详细介绍
2013/04/27 PHP
php实现模拟登陆方正教务系统抓取课表
2015/05/19 PHP
PHP数组编码gbk与utf8互相转换的两种方法
2016/09/01 PHP
PHP类与对象后期静态绑定操作实例详解
2018/12/20 PHP
JQuery 获取json数据$.getJSON方法的实例代码
2013/08/02 Javascript
JavaScript中的console.trace()函数介绍
2014/12/29 Javascript
JavaScript编程中容易出BUG的几点小知识
2015/01/31 Javascript
javascript实现checkbox全选的代码
2015/04/30 Javascript
js操作table元素实现表格行列新增、删除技巧总结
2015/11/18 Javascript
基于javascript实现图片切换效果
2016/04/17 Javascript
jQuery stop()用法实例详解
2016/07/28 Javascript
详解webpack 多页面/入口支持&amp;公共组件单独打包
2017/06/29 Javascript
vue中计算属性(computed)、methods和watched之间的区别
2017/07/27 Javascript
详解react、redux、react-redux之间的关系
2018/04/11 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
2019/04/08 Javascript
解决layer.msg 不居中 ifram中的问题
2019/09/05 Javascript
javascript随机变色实例代码
2019/10/15 Javascript
vue使用axios实现excel文件下载的功能
2020/07/16 Javascript
vue中实现弹出层动画效果的示例代码
2020/09/25 Javascript
[04:53]DOTA2英雄基础教程 祈求者
2014/01/03 DOTA
使用Python发送邮件附件以定时备份MySQL的教程
2015/04/25 Python
对python指数、幂数拟合curve_fit详解
2018/12/29 Python
Python之时间和日期使用小结
2019/02/14 Python
flask框架渲染Jinja模板与传入模板变量操作详解
2020/01/25 Python
Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)
2021/01/29 Python
HTML5 canvas基本绘图之绘制五角星
2016/06/27 HTML / CSS
英国户外装备和冒险服装零售商:alloutdoor
2018/01/30 全球购物
计算机应用与科学个人的自我评价
2013/11/15 职场文书
《寓言两则》教学反思
2014/02/27 职场文书
学校三节实施方案
2014/06/09 职场文书
大学生毕业个人总结
2015/02/15 职场文书
公司老总年会致辞
2015/07/30 职场文书
趣味运动会口号
2015/12/24 职场文书
python工具dtreeviz决策树可视化和模型可解释性
2022/03/03 Python
vscode远程免密登入Linux服务器的配置方法
2022/06/28 Servers
了解MySQL查询语句执行过程(5大组件)
2022/08/14 MySQL