<el-table
border
:data="tableData"
default-expand-all
height="700"
row-key="id"
ref="table">
<el-table-column align="center" width="50"></el-table-column>
<el-table-column align="center" width="50">
<template slot="header" slot-scope="scope">
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleSelectAll"></el-checkbox>
</template>
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isChecked" :indeterminate="scope.row.isIndeterminate" @change="handleSelectTr($event, scope.row)"></el-checkbox>
</template>
</el-table-column>
<el-table-column align="center" prop="sequence" label="序号"></el-table-column>
<el-table-column align="center" prop="requireNum" label="需求编号"></el-table-column>
<el-table-column align="center" prop="requireName" label="名称"></el-table-column>
<el-table-column align="center" prop="project" label="所属项目"></el-table-column>
<el-table-column align="center" prop="modularId" label="所属模块"></el-table-column>
<el-table-column align="center" prop="priority" label="优先级"></el-table-column>
<el-table-column align="center" prop="extend7" label="重要程度"></el-table-column>
<el-table-column align="center" prop="requireSource" label="需求来源"></el-table-column>
<!-- <el-table-column align="center" prop="sourcePerson" label="来源人"></el-table-column> -->
<!-- <el-table-column align="center" prop="dealingPeople" label="处理人"></el-table-column> -->
<el-table-column align="center" prop="endDate" label="截止时间"></el-table-column>
<el-table-column align="center" prop="createDate" label="完成时间"></el-table-column>
<el-table-column align="center" prop="requireState" label="状态"></el-table-column>
<!-- <el-table-column align="center" prop="extend2" label="创建者"></el-table-column> -->
<!-- <el-table-column align="center" prop="planUserName" label="规划人"></el-table-column> -->
</el-table>
<el-pagination layout="prev, pager, next" :current-page.sync="pagination.currentPage" @current-change="currentChange" :total="pagination.total"></el-pagination>
data() {
return {
tableData: tableData, // 数据自行模拟
checkAll: false,
isIndeterminate: false,
checkedList: [],
nodesTotal: {
checkTotal: 0,
total: 0
},
pagination: {
currentPage: 1,
total: tableData.length + tableData2.length
},
flattenCheckedList: [] // 最终的选中的数据
}
},
computed: {
},
watch: {
},
mounted() {
},
created() {
this.currentChange(1);
},
methods: {
// 分页切换
currentChange(pageNum){
if(pageNum == 1){
this.tableData = this.initData(tableData);
}else{
this.tableData = this.initData(tableData2);
}
// 获取当前页所有节点个数
this.nodesTotal = this.queryNodesTotal(this.tableData);
// 设置当前页的节点选中
if(this.checkedList[pageNum - 1]){
for(let i = 0; i < this.checkedList[pageNum - 1].length; i++){
this.setInitChecked(this.checkedList[pageNum - 1][i], this.tableData);
}
}
this.setGlobalCheckBoxState();
},
// 初始化数据---模拟请求数据
initData(data){
data.map((item, index) => {
item.isChecked = false;
item.isIndeterminate = false;
if(item.children && item.children.length != 0){
this.initData(item.children);
}
});
return data;
},
// 递归设置初始化节点状态
setInitChecked(row, data) {
for(let i = 0; i < data.length; i++){
if(row.id == data[i].id){
data[i].isChecked = row.isChecked;
data[i].isIndeterminate = row.isIndeterminate;
break;
}
if (data[i].children && data[i].children.length != 0) {
this.setInitChecked(row, data[i].children);
}
}
},
// 全选
handleSelectAll(val){
// 设置全选或者取消全选
let checkedList = this.deepClone(this.setTreeRecursion(this.tableData, val));
this.checkedList[this.pagination.currentPage - 1] = val ? checkedList : undefined;
// 设置 “全选 checkbox” 的不确定状态
this.isIndeterminate = val ? false : this.checkedList.some(item => item);
this.handleCheckedList();
},
// checkbox 切换 ----- 递归设置选中与取消选中,并返回选中的数据
setTreeRecursion(treeData = [], val, arr = []) {
for (let item of treeData) {
item.isChecked = val; // 切换当前 checkbox 选中状态
item.isIndeterminate = false; // 切换当前 checkbox 时,要取消 isIndeterminate
if(val) arr.push(item);
if (item.children && item.children.length != 0) {
this.setTreeRecursion(item.children, val, arr);
}
}
return arr;
},
// 设置全局(最外层)复选框的状态
setGlobalCheckBoxState(){
// 页码 和 数组脚标对应
let arrPos = this.pagination.currentPage - 1;
// 判断 “所有页” 是否有选中的数据 ----- 设置 “全选 checkbox” 的状态
let hasValue = this.checkedList.some(item => item);
if(hasValue){
// 如果 “当前页” 有选中的数据
if(this.checkedList[arrPos]){
this.checkAll = this.checkedList[arrPos].length === this.nodesTotal.total;
this.isIndeterminate = this.checkedList[arrPos].length > 0 && this.checkedList[arrPos].length < this.nodesTotal.total;
}else{
this.checkAll = false;
this.isIndeterminate = true;
}
}else{
this.checkAll = false;
this.isIndeterminate = false;
}
},
// 选中的节点集合数据处理
handleCheckedList(){
this.flattenCheckedList = [].concat.apply([], this.checkedList);
this.flattenCheckedList = this.flattenCheckedList ? this.flattenCheckedList : [];
for(let i = 0; i < this.flattenCheckedList.length; i++){
if(!this.flattenCheckedList[i]){
this.flattenCheckedList.splice(i--, 1);
}
}
console.log(this.flattenCheckedList)
},
// 清空选中的数据和选中状态
emptyCheckedList(){
this.checkedList = [];
this.flattenCheckedList = [];
this.checkAll = false;
this.isIndeterminate = false;
this.initData(this.taskListData);
},
// 行全选
handleSelectTr(val, row){
// 根据 id pid 获取到的节点
let getNode = this.queryNodeById(this.tableData, row.id, row.superRequireId);
// 当前节点 和 当前节点的所有父级节点集合
let currentNode = getNode.cNode, parentNode = getNode.pNodes;
// 递归当前节点以及所有子节点 设置全部选中与否
this.setTreeRecursion([currentNode], val);
// 递归每个父节点的全部子节点个数,以及每个父节点的全部选中的子节点个数
parentNode.map(item => {
let num = this.queryNodesTotal(item.children);
let childrenNum = num.total;
let childrenCheckNum = num.checkTotal;
// 设置 父节点的选中 与 isIndeterminate
item.isChecked = childrenNum == childrenCheckNum;
item.isIndeterminate = childrenCheckNum > 0 && childrenCheckNum < childrenNum;
})
// 获取 “当前页” 中所有选中的数据
let checkedList = this.deepClone(this.getCheckedNodes(this.tableData));
// 赋值选中的数据
this.checkedList[this.pagination.currentPage - 1] = checkedList.length ? checkedList : undefined;
this.setGlobalCheckBoxState();
this.handleCheckedList();
},
// 递归获取当前页中所有选中的数据
getCheckedNodes(treeData = [], arr = []) {
for (let item of treeData) {
if(item.isChecked || item.isIndeterminate) arr.push(item);
if (item.children && item.children.length != 0) {
this.getCheckedNodes(item.children, arr);
}
}
return arr;
},
/**
* 递归-----根据 id 查询当前节点 和 根据 pId 查询 当前节点的所有父级节点集合
* @param node 树的源数据
* @param nodeId 节点的 id
* @param nodePid 节点的 pId
* @param temp 返回的匹配的节点数据集合
* @returns {{pNodes: *[], cNode: {}}} pNodes: 父级节点集合,cNode:当前节点
*/
queryNodeById(node, nodeId, nodePid, temp = {cNode: {}, pNodes: []}){
let forFn = (arr, id, pId) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === id) {
temp.cNode = arr[i];
break;
}else if (arr[i].id === pId) {
temp.pNodes.push(arr[i]);
forFn(node, id, arr[i].pId);
break;
} else {
if (arr[i].children) {
forFn(arr[i].children, id, pId)
}
}
}
}
forFn(node, nodeId, nodePid);
return temp;
},
/**
* 递归-----查询 树组件 共有多少节点
* @param data data树的源数据
* @param num num 总节点数
* @returns {{checkTotal: number, total: number}} checkTotal: 选中的节点总数,total: 所有节点总数
*/
queryNodesTotal(data, num = { total: 0, checkTotal: 0 }){
let forFn = nodes => {
for(let i = 0; i < nodes.length; i++){
if(nodes[i].isChecked != undefined && nodes[i].isChecked != null){
num.total++;
if(nodes[i].isChecked) num.checkTotal++;
}
if(nodes[i].children && nodes[i].children.length != 0){
forFn(nodes[i].children);
}
}
}
forFn(data);
return num;
},
/**
* 定义一个深拷贝函数 接收目标 target 参数
* @param {Object} target
*/
deepClone(target) {
// 定义一个变量
let result;
// 如果当前需要深拷贝的是一个对象的话
if (typeof target === 'object') {
// 如果是一个数组的话
if (Array.isArray(target)) {
result = []; // 将 result 赋值为一个数组,并且执行遍历
for (let i in target) {
// 递归克隆数组中的每一项
result.push(this.deepClone(target[i]))
}
// 判断如果当前的值是 null 的话,直接赋值为 null
}else if(target === null) {
result = null;
// 判断如果当前的值是一个 RegExp 对象的话,直接赋值
}else if(target.constructor === RegExp){
result = target;
}else{
// 否则是普通对象,直接 for in 循环,递归赋值对象的所有值
result = {};
for (let i in target) {
result[i] = this.deepClone(target[i]);
}
}
// 如果不是对象的话,就是基本数据类型,那么直接赋值
} else {
result = target;
}
// 返回最终结果
return result;
},
}