element ui树形表格如下:
它的数据格式为:使用children字段来存放子级数据
tableData: [
{
id: 1,
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
id: 2,
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
},
{
id: 3,
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
children: [
{
id: 31,
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
},
{
id: 32,
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
},
],
},
{
id: 4,
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄",
},
],
element ui 树形&懒加载 表格如下:
默认是不请求子级数据的,当点击下拉icon时再发起请求
完整代码:
DOM: 需注意以下属性
row-key="id"
lazy
:load="load"
:tree-props="{
children: 'children',
hasChildren: 'hasChildren',
}"
<el-table
:data="tableData1"
style="width: 100%"
row-key="id"
border
lazy
:load="load"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
数据:就是普通的数组,没有子级数据的概念
tableData1: [
{
id: 1,
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
id: 2,
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
},
{
id: 3,
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
hasChildren: true,
},
{
id: 4,
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄",
},
],
懒加载事件:
load(tree, treeNode, resolve) {
// 这里发请求,请求当前点击的子级数据data,然后交给resolve处理,就可以正确展示子级数据
setTimeout(() => {
resolve(data);
}, 300);
},
发现树形懒加载多选表格有两个问题:
1、勾选父级时子级不会勾选上
一般我们实现表格多选功能是这样的:这里不再使用这种方式
<el-table-column
type="selection"
width="55">
</el-table-column>
第一步:需要我们手动写个勾选表头和勾选列
<el-table-column type="test" align="left" width="55">
<!-- 表头的全选勾选框,indeterminate:是否半选状态,handleCheckAllDetail:全选事件 -->
<template slot="header" slot-scope="scope">
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAllDetail"
@change="handleCheckAllDetail"
></el-checkbox>
</template>
<!-- 表格数据列单行勾选框,使用checked属性决定是否勾选,单行勾选事件 -->
<template slot-scope="scope">
<el-checkbox
v-model="scope.row.checked"
@change="handleCheckDetail(scope.row, $event)"
></el-checkbox>
</template>
</el-table-column>
第二步: 定义数据
checkAllDetail: false,
isIndeterminate: false,
第三步:编写handleCheckAllDetail、handleCheckDetail函数,
每次勾选时要做的事:
处理全选、半选状态;
用个数组处理勾选行的数据,勾选时将数据存起来,取消勾选时将数据删除;
若勾选父级时,将子级的数据也全部勾选;取消勾选反之;
若勾选子级时,也要计算父级是否应该勾选上;
第四步:点击下拉icon时也要数据子级数据的勾选状态
这里涉及到一个很重要的问题:如何拿到子级数据:先给表格绑定ref属性
this.$refs.mulTable.store.states.lazyTreeNodeMap这个可以取到所有展开的子级数据
数据格式为:{父级id1: [{子数据1}, {子数据2}], 父级id2: [{子数据}] }
举个例子:当勾选单个数据时如何处理:
// 单条数据的勾选操作
handleCheckDetail(row, val) {
// 如果勾选的是子级数据:那么要计算子级决定父级勾选状态
if (row.parent) {
let parentId = row.parent; //父级id
let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap; // 所有展开项的懒加载数据
let parentItem = loadChildData[parentId]; //当前父级下的所有子数据
// 判断当前下的所有子数据是否全部勾选上了
let checked = parentItem?.every(function (currentValue, index, arr) {
return currentValue.checked;
});
// 设置父级数据的勾选状态
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].id === parentId) {
this.$set(this.list[i], "checked", checked);
}
}
// 勾选则将id添加进去,否则删除id【selectArrIds是用来存放勾选数据的id的数组】
if (checked) {
this.selectArrIds.push(parentId);
} else {
let index = this.selectArrIds.indexOf(parentId);
if (index !== -1) {
this.selectArrIds.splice(index, 1);
}
}
} else {
// 如果当前点击的是父级数据:那么父级决定子级状态
let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap; // 所有展开项的懒加载数据
let datas = loadChildData[row.id]; //当前父级下的所有子数据
// 将父级的勾选状态同步给子级
datas?.forEach((item) => {
this.$set(item, "checked", val);
});
// 勾选则将id添加进去,否则删除id【selectArrIds是用来存放勾选数据的id的数组】
if (val) {
this.selectArrIds.push(row.id);
} else {
let index = this.selectArrIds.indexOf(row.id);
if (index !== -1) {
this.selectArrIds.splice(index, 1);
}
}
}
// 计算半选和全选状态
let totalCount = this.list.length;
this.checkAllDetail =
totalCount === this.selectArrIds.length ? true : false;
this.isIndeterminate =
this.selectArrIds.length > 0 && this.selectArrIds.length < totalCount;
},
当勾选全选checkbox时如何处理:
handleCheckAllDetail(val) {
this.isIndeterminate = false;
let setIds = [];
this.list.forEach((item, index) => {
if (
val &&
this.selectArrIds.indexOf(item.id) === -1
) {
setIds.push(item.id);
}
});
if (val) {
this.selectArrIds = setIds;
} else {
this.selectArrIds = [];
}
// 若有展开项,则将子级也勾选上
this.setChildCheck(val);
},
setChildCheck方法:
// 设置子级的数据勾选状态
setChildCheck(val) {
let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap;
if (Object.keys(loadChildData).length > 0) {
let keys = [];
for (let key in loadChildData) {
keys.push(key);
}
for (let i = 0; i < keys.length; i++) {
let datas = loadChildData[keys[i]];
datas?.forEach((item) => {
// 按父级的勾选状态去控制子级的勾选状态
let isChecked;
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].id === item.parent) {
isChecked = this.list[i].checked;
}
}
this.$set(item, "checked", isChecked);
});
}
}
},
效果如下:
element ui懒加载树形表格-勾选
2、对子级数据进行删除、修改、添加操作时,不会更新子级数据
这个问题目前还没实现,但是估计也是通过this.$refs.mulTable.store.states.lazyTreeNodeMap处理数据,稍后更新~~
PS:后来发现了另外一个非常棒的UI库,可以考虑使用~~
vxe-table v4文章来源:https://www.toymoban.com/news/detail-406036.html
文章来源地址https://www.toymoban.com/news/detail-406036.html
到了这里,关于element ui 树形-懒加载-表格-多选 勾选问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!