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 相关文章推荐
javascript使用activex控件的代码
Jan 27 Javascript
通过正则格式化url查询字符串实现代码
Dec 28 Javascript
html+js实现动态显示本地时间
Sep 21 Javascript
实例剖析AngularJS框架中数据的双向绑定运用
Mar 04 Javascript
简单谈谈Vue 模板各类数据绑定
Sep 25 Javascript
jQuery的三种bind/One/Live/On事件绑定使用方法
Feb 23 Javascript
使用vue.js编写蓝色拼图小游戏
Mar 17 Javascript
Vue通过URL传参如何控制全局console.log的开关详解
Dec 07 Javascript
详解vue axios用post提交的数据格式
Aug 07 Javascript
解决element UI 自定义传参的问题
Aug 22 Javascript
vue中的适配px2rem示例代码
Nov 19 Javascript
vue elementUI 表单校验功能之数组多层嵌套
Jun 04 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
海贼王动画变成“真人”后,凯多神还原,雷利太帅了!
2020/04/09 日漫
ThinkPHP实现简单登陆功能
2017/04/28 PHP
Yii 2.0如何使用页面缓存方法示例
2017/05/23 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
优化JavaScript脚本的性能的几个注意事项
2006/12/22 Javascript
js arguments对象应用介绍
2012/11/28 Javascript
JS模块与命名空间的介绍
2013/03/22 Javascript
基于JQuery实现仿网易邮箱全屏动感滚动插件fullPage
2015/09/20 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
几种tab切换详解
2017/02/03 Javascript
不得不看之JavaScript构造函数及new运算符
2017/08/21 Javascript
深度了解vue.js中hooks的相关知识
2019/06/14 Javascript
vue实现下拉加载其实没那么复杂
2019/08/13 Javascript
解决在layer.open中使用时间控件laydate失败的问题
2019/09/11 Javascript
vue中音频wavesurfer.js的使用方法
2020/02/20 Vue.js
JS错误处理与调试操作实例分析
2020/04/13 Javascript
javascript 内存模型实例详解
2020/04/18 Javascript
用Python的Django框架编写从Google Adsense中获得报表的应用
2015/04/17 Python
你真的了解Python的random模块吗?
2017/12/12 Python
Python进程间通信Queue实例解析
2018/01/25 Python
Python爬虫包BeautifulSoup学习实例(五)
2018/06/17 Python
linux查找当前python解释器的位置方法
2019/02/20 Python
Python生成器的使用方法和示例代码
2019/03/04 Python
Django多层嵌套ManyToMany字段ORM操作详解
2020/05/19 Python
详解css position 5种不同的值的用法
2019/07/30 HTML / CSS
解决H5的a标签的download属性下载service上的文件出现跨域问题
2019/07/16 HTML / CSS
台湾母婴用品购物网站:Infant婴之房
2018/06/15 全球购物
英国网上超市:Ocado
2020/03/05 全球购物
Internet主要有哪些网络群组成
2015/12/24 面试题
公司会计主管岗位责任制
2014/03/01 职场文书
差生评语大全
2014/05/04 职场文书
教师师德师风自我剖析材料
2014/09/29 职场文书
教师群众路线学习心得体会
2014/11/04 职场文书
导游词之大雁塔景区
2019/09/17 职场文书
导游词之京东大峡谷旅游区
2019/10/29 职场文书
Java异常体系非正常停止和分类
2022/06/14 Java/Android