ElementUI Table表格树形数据多选框实现树形控件式选中效果

实现效果

  1. 选中父级时会选中所有子级
    在这里插入图片描述
  2. 表头全选选中所有父级与子级
    在这里插入图片描述

涉及代码

  1. html elementUI表格部分
<el-table
	:data="orgs"
	style="width: 100%;"
	size="medium"
	class="table"
	ref="multipleTable"
	header-cell-class-name="table-header"
	@selection-change="handleSelectionChange"
	:tree-props="{children: 'children'}"
	row-key="id"
	@select="rowSelect"
	@select-all="selectAll">
	<el-table-column type="selection" width="55" align="center"></el-table-column>
	.....
	.....
</el-table>
ref="multipleTable" //注册引用信息,用来之后获取表格所有row(行数据)
@select="rowSelect" //监听elementUI表格事件:当用户手动勾选数据行的 Checkbox 时触发的事件
@select-all="selectAll" //监听当用户手动勾选全选 Checkbox 时触发的事件
  1. Script部分
/*注意在获取初始数据时,所有节点(包括子节点)都增加一个isChecked 标志参数*/
rowSelect(selection, row) {
    if (row.children) { //只对有子节点的行响应
        if (!row.isChecked) {   //由行数据中的元素isChecked判断当前是否被选中
            row.children.map((item) => { //遍历所有子节点
                this.$refs.multipleTable.toggleRowSelection(item, true); //切换该子节点选中状态
                /*
                方法名                    说明                                      参数
                                     用于多选表格,切换某一行的选中状态,         row, selected
                toggleRowSelection   如果使用了第二个参数,则是设置这一行
                                     选中与否(selected 为 true 则选中)
                 */
                item.isChecked = true;
            });
            row.isChecked = true; //当前行isChecked标志元素切换为false
        } else {
            row.children.map((item) => {
                this.$refs.multipleTable.toggleRowSelection(item, false);
                item.isChecked = false;
            });
            row.isChecked = false;
        }
        // console.log(this.multipleSelection, row);
    }
},
selectAll(selection) {
    // selection 是选中的数据集合
    this.$refs.multipleTable.data.map((items) => { //使用$ref获取注册的子组件信息,用data获取所有行,并用map函数遍历行
        if (items.children) {
            if (!items.isChecked) { //若遍历出来的行未选中
                this.$refs.multipleTable.toggleRowSelection(items, true); //行变为选中状态
                items.isChecked = true; //更新标志参数
                items.children.map((item) => { //遍历子节点并改变状态与标志参数
                    this.$refs.multipleTable.toggleRowSelection(item, true);
                    item.isChecked = true;
                });
            } else { //选中状态同理
                this.$refs.multipleTable.toggleRowSelection(items, false);
                items.isChecked = false;
                items.children.map((item) => {
                    this.$refs.multipleTable.toggleRowSelection(item, false);
                    item.isChecked = false;
                });
            }
        }
        else{
            if (!items.isChecked) items.isChecked = true;
            else items.isChecked = false;
        }
    });
    // console.log(this.orgs)
}

感想

目前这样仍然存在一个问题:当使用表头选择框进行全选时,若已选择某些数据,无法直接全选,但不会bug,多点几次能够完成全选,我未对此再进行优化,如下有两种情况:

  1. 存在已选-拥有子节点
  2. 存在已选-没有子节点
    在这里插入图片描述
    没有使用什么复杂算法,就是判断情况,遍历处理,代码比较紊乱,欢迎dalao优化指正,或者优化判断上述两种未考虑的情况。

涉及一个js小知识

在学习的时候,上述代码中用来遍历的JS函数map(),在教程中提到:

map()为操作数组的一种方法,官方文档显示:

  1. map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
  2. map() 方法按照原始数组元素顺序依次处理元素。
  3. 注意: map() 不会对空数组进行检测。
  4. 注意: map() 不会改变原始数组。

但上述代码实际使用中发现,使用map()函数是能够改变原数组的值,关于这个问题,在 这个帖子 上看到了实验结果。
以下为原贴实验内容:

  1. 当数组为基础类型时原数组不变:
let array=[1,2,3,4,5]
let newArray=array.map((item) => item*2)
console.log(array); // [1,2,3,4,5]
console.log(newArray); //[2, 4, 6, 8, 10]
  1. 当数组为引用类型时原数组发生改变:
let array = [{ name: 'Anna', age: 16 }, { name: 'James', age: 18 }]
let newArray=array.map((item) => {
	item.like='eat';
	return item;
})
console.log(array); // [{ name: 'Anna', age: 16,like: "eat"},{ name: 'James', age: 18,like: "eat"}]
console.log(newArray); //[{ name: 'Anna', age: 16,like: "eat"},{ name: 'James', age: 18,like: "eat"}]

由此得知,我代码中遍历的都是引用类型数据(Object数组),所以能够对原数组进行更改。

希望能帮助到各位。

  • 13
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
好的,我可以为您解答。实现表格加载树形数据,需要以下步骤: 1. 在表格中添加树形数据列,例如: ``` <el-table-column prop="name" label="名称"> <template slot-scope="scope"> <span :style="{marginLeft: scope.row.level * 20 + 'px'}">{{scope.row.name}}</span> </template> </el-table-column> ``` 其中,prop属性表示数据对应的字段,label属性表示列的名称,slot-scope属性表示插槽作用域,可以使用scope来获取当前行的数据。在模板中,根据当前数据的层级(level)来动态设置名称的缩进。 2. 在数据源中添加level字段,表示当前数据的层级,例如: ``` data: [ { name: '节点1', level: 0, children: [ { name: '节点1-1', level: 1 }, { name: '节点1-2', level: 1 } ] }, { name: '节点2', level: 0, children: [ { name: '节点2-1', level: 1, children: [ { name: '节点2-1-1', level: 2 } ] } ] } ] ``` 其中,children属性表示当前节点的子节点,如果没有子节点,可以不添加该属性。 3. 在表格中添加expand属性,表示是否展开当前行的子节点,例如: ``` <el-table :data="data" :expand-row-keys="expandKeys" @expand-change="handleExpandChange"> <el-table-column type="expand"> <template slot-scope="props"> <el-table :data="props.row.children"> <el-table-column prop="name" label="名称"> <template slot-scope="scope"> <span :style="{marginLeft: (scope.row.level + 1) * 20 + 'px'}">{{scope.row.name}}</span> </template> </el-table-column> </el-table> </template> </el-table-column> <el-table-column prop="name" label="名称"> <template slot-scope="scope"> <span :style="{marginLeft: scope.row.level * 20 + 'px'}">{{scope.row.name}}</span> </template> </el-table-column> </el-table> ``` 其中,type属性为expand表示当前列为展开列,通过props.row.children获取当前行的子节点数据,然后再次渲染表格。在子表格中,名称的缩进需要根据父节点的层级来计算。 4. 在组件中添加处理展开事件的方法,例如: ``` export default { data() { return { data: [...], expandKeys: [] } }, methods: { handleExpandChange(row, expandedRows) { if (expandedRows) { this.expandKeys.push(row.name) } else { const index = this.expandKeys.indexOf(row.name) if (index >= 0) { this.expandKeys.splice(index, 1) } } } } } ``` 其中,expandKeys数组记录当前已展开的行的名称,handleExpandChange方法用于处理展开事件,通过判断expandedRows参数来确定当前行是否展开,然后根据名称来添加或删除expandKeys数组中的元素。 以上就是模拟ElementUI实现表格加载树形数据的步骤,希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值