vue+element UI實現(xiàn)樹形表格帶復選框的示例代碼
更新時間:2019年04月16日 11:25:03 作者:bamboozjy
這篇文章主要介紹了vue+element UI實現(xiàn)樹形表格帶復選框的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
一:在component文件夾下新建如下treeTable文件夾,里面有2個文件:

eval.js:將數(shù)據(jù)轉(zhuǎn)換成樹形數(shù)據(jù)
/**
* @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: {
// 格式化數(shù)據(jù)源
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;
},
//設(shè)置表頭全選
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;"
}
})
]);
},
//功能函數(shù):選中部分子集
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);
}
});
},
//設(shè)置父級為 未選中狀態(tài)(父級的父級沒改變-有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; //終止此次循環(huán),減少循環(huán)次數(shù)
}
});
}
if (v.child) {
this.setparentfalse(v.child, id, level);
}
});
},
//設(shè)置父級為 選中狀態(tài)
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) {
//確保當前點擊的在該父級內(nèi)
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,防止上次已經(jīng)是false的狀態(tài)
this.isallchecked(this.formatData);
//3、設(shè)置多選框的狀態(tài)
if (!row.checks) {
this.setparentfalse(this.formatData, row.id, row._level); //設(shè)置父級選中的狀態(tài)為false
document.getElementById("chooseall").checked = false; //設(shè)置全選框的狀態(tài)
} else {
this.setparenttrue(this.formatData, row.id, row._level); //設(shè)置父級選中的狀態(tài)為true
}
if (this.key) {
document.getElementById("chooseall").checked = true; //設(shè)置全選框的狀態(tài)
}
}
},
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: "無"
}
]
}
]
}
]
}
]
};
},
最終效果:

這樣就大工告成了,想要了解更多,可以關(guān)注 vue-element-admin,一個很不錯的后臺管理模版
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- 關(guān)于extjs treepanel復選框選中父節(jié)點與子節(jié)點的問題
- vue基于element-ui的三級CheckBox復選框功能的實現(xiàn)代碼
- vuejs+element UI table表格中實現(xiàn)禁用部分復選框的方法
- element的el-tree多選樹(復選框)父子節(jié)點關(guān)聯(lián)不關(guān)聯(lián)
- el-table?選中行與復選框相互聯(lián)動的實現(xiàn)步驟
- Vue3+ElementUI 多選框中復選框和名字點擊方法效果分離方法
- 使用element組件table表格實現(xiàn)某條件下復選框無法勾選
- Vue el-table復選框全部勾選及勾選回顯功能實現(xiàn)
- el-table表格點擊該行任意位置時也勾選上其前面的復選框
相關(guān)文章
Vue3中defineEmits、defineProps?不用引入便直接用
這篇文章主要介紹了Vue3中defineEmits、defineProps?不用引入便直接用,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09

