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 相关文章推荐
js计算字符串长度包含的中文是utf8格式
Oct 15 Javascript
Jquery实现仿京东商城省市联动菜单
Nov 19 Javascript
jQuery实现右下角可缩放大小的层完整实例
Jun 20 Javascript
Angular懒加载机制刷新后无法回退的快速解决方法
Aug 30 Javascript
微信公众号菜单配置微信小程序实例详解
Mar 31 Javascript
javascript 玩转Date对象(实例讲解)
Jul 11 Javascript
Vue实例中生命周期created和mounted的区别详解
Aug 25 Javascript
jQury Ajax使用Token验证身份实例代码
Sep 22 Javascript
基于vue-cli创建的项目的目录结构及说明介绍
Nov 23 Javascript
React Native 使用Fetch发送网络请求的示例代码
Dec 02 Javascript
vue-router为激活的路由设置样式操作
Jul 18 Javascript
详解React的回调渲染模式
Sep 10 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
收音机鉴频器对声音的影响和频偏分析
2021/03/02 无线电
sphinx增量索引的一个问题
2011/06/14 PHP
set_include_path和get_include_path使用及注意事项
2013/02/02 PHP
php建立Ftp连接的方法
2015/03/07 PHP
PHP中PDO事务处理操作示例
2018/05/02 PHP
Valerio 发布了 Mootools
2006/09/23 Javascript
javascript 复杂的嵌套环境中输出单引号和双引号
2009/05/26 Javascript
运用jquery实现table单双行不同显示并能单行选中
2009/07/25 Javascript
鼠标右击事件代码(asp.net后台)
2011/01/27 Javascript
jQuery.extend()的实现方式详解及实例
2013/06/29 Javascript
javascript单例模式的简单实现方法
2015/07/25 Javascript
如何解决hover在ie6中的兼容性问题
2016/12/15 Javascript
windows下vue-cli导入bootstrap样式
2017/04/25 Javascript
vue2 自定义动态组件所遇到的问题
2017/06/08 Javascript
Express的HTTP重定向到HTTPS的方法
2018/06/06 Javascript
Node.js 使用request模块下载文件的实例
2018/09/05 Javascript
微信小程序使用template标签实现五星评分功能
2018/11/03 Javascript
webpack自动打包和热更新的实现方法
2019/06/24 Javascript
基于Vue实现微前端的示例代码
2020/04/24 Javascript
python实现堆栈与队列的方法
2015/01/15 Python
Python开发如何在ubuntu 15.10 上配置vim
2016/01/25 Python
import的本质解析
2017/10/30 Python
Python从数据库读取大量数据批量写入文件的方法
2018/12/10 Python
python自动识别文本编码格式代码
2019/12/26 Python
Keras使用tensorboard显示训练过程的实例
2020/02/15 Python
Python操作MySQL数据库的示例代码
2020/07/13 Python
加拿大最大的箱包及旅游配件零售商:Bentley Leathers
2017/07/19 全球购物
招聘专员岗位职责
2014/03/07 职场文书
计划生育宣传标语
2014/06/21 职场文书
个人剖析材料及整改措施
2014/10/07 职场文书
三峡大坝导游词
2015/01/31 职场文书
电子商务专业求职信范文
2015/03/19 职场文书
死者家属慰问信
2015/03/24 职场文书
入党转正申请报告
2015/05/15 职场文书
家装电话营销开场白
2015/05/29 职场文书
给校长的建议书作文300字
2015/09/14 职场文书