el-tree结合el-table的选择器

el-tree结合el-table的选择器

最近开发遇见一个需求,一棵五个层级的tree,点击任意节点加载该节点下的学生数据。本身这个需求是容易实现的,根据节点进行分页嘛~

但做成查询条件后,被告知要支持分页,当跨页选择数据和反显数据时,就遇到了困难

在这里插是入图片描述
组件一次请求最多两百条数据,支持当前页全选,选择的班级和学生按照tag的样式展示在上方。
1.选择的学生数据存储在window.localStorage中,el-table的select-change事件将回传数据行,存储在localStorage之前要去重,否则数据量爆炸将使浏览器崩溃。

<el-table
        ref="multipleTable"
        v-loading="loading"
        max-height="288px"
        border
        stripe
        empty-text="没有数据"
        :data="pageData ? pageData.list : []"
        @selection-change="handleSelectionChange"
        @select="cancelCheck"
        @select-all="checkAll"
  >
 /**
         * 学生选择切换 根据用户选中的学生,渲染到已选学生列表
         * 每次改变勾选都会触发多次,将选择的列表逐个传递
         * */
        handleSelectionChange(v) {
            // console.log('变化了');
            this.showCommit = false;
            if (!v) return false;
            // console.log('用户当前选择的学生111', v);
            const oldChecked = JSON.parse(window.localStorage.getItem('tempCheckedStudentIds')) || [];
            let temp = null;
            if (this.isFiltering) {
                temp = oldChecked.concat(v);
            } else {
                if (v.length) {
                    if (oldChecked && oldChecked.length) {
                        temp = this.getTemp(oldChecked.concat(v));
                    } else {
                        temp = v;
                    }
                } else {
                    temp = this.getTemp(oldChecked.concat(v));
                }
            }
            this.isFiltering = false;
            window.localStorage.setItem('tempCheckedStudentIds', JSON.stringify(temp));
            this.getCheckedStudentIds(temp);
        },
        // 取消选择时触发,将学生名字取消,id从中删除
        cancelCheck(selection, row) {
            this.deleteStudentId([row]);
        },
        // 表格全选框改变时取消,这里主要用在该分页数据全部取消时,弥补上两个方法监测不到
        checkAll(selection) {
            if (selection.length === 0) {
                this.deleteStudentId(this.pageData.list);
            }
        },
//将取消选择的数据从localStorage删除掉,为了做选择学生的交互效果,否则不用这么麻烦
deleteStudentId(list) {
            const oldChecked = JSON.parse(window.localStorage.getItem('tempCheckedStudentIds')) || [];
            if (oldChecked.length === 0) {
                return false;
            }
            for (let j = 0; j < list.length; j++) {
                for (let i = 0; i < oldChecked.length; i++) {
                    if (oldChecked[i].subjectId === list[j].subjectId) {
                        oldChecked.splice(i, 1);
                    }
                }
            }
            window.localStorage.setItem('tempCheckedStudentIds', JSON.stringify(oldChecked));
            this.getCheckedStudentIds(oldChecked);
        }
// 数组去重
        getTemp(list) {
            const tempList = [];
            const ids = [];
            list.forEach(item => {
                if (item.hasOwnProperty('subjectId')) {
                    if (!ids.includes(item['subjectId'])) {
                        ids.push(item['subjectId']);
                        tempList.push(item);
                    }
                }
            });
            return tempList;
        },
/**
         * 切换成员表格成员选中状态
         * */
        toggleSelection(list) {
            if (list && list.length) {
                list.forEach(row => {
                    this.$refs.multipleTable.toggleRowSelection(row);
                });
            } else {
                this.$refs.multipleTable.clearSelection();
            }
            this.$forceUpdate();
        },
        /**
         * 获取当前选中的所有成员id
         * @param temp 临时存储的用户对象
         * */
        getCheckedStudentIds(temp) {
            const {
                ids,
                names
            } = this.setCheckedByKey(temp);
            this.checkedStudentIds = ids;
            this.showCheckedStudentName = names.length ? names.join(',') : '';
            setTimeout(() => {
                this.showCommit = true;
            }, 300);
        },
        /**
         * 通过指定类型过滤数据,数组去重
         * @param list
         * */
        setCheckedByKey(list) {
            const ids = [];
            const names = [];
            list.forEach(item => {
                if (item.hasOwnProperty('subjectId')) {
                    if (!ids.includes(item['subjectId'])) {
                        ids.push(item['subjectId']);
                        names.push(item['subjectName']);
                    }
                }
            });
            return {
                ids,
                names
            };
        }

最后,记得在打开弹窗组件的时候把数据全部传回来渲染。
子组件向父组件传值的时候,将选择的所有学生即window.localStorage的数据转存之后再清除,打开子组件再回传。是因为打开组件时只加载了第一页分页,而关闭弹窗前无法确定用户选择了哪些分页的数据,我们必须加载它们并且渲染,所以备份一次选择的数据。

           this.paging();
           this.loading = false;
            window.localStorage.setItem('tempCheckedStudentIds', JSON.stringify(this.localStorageList));
            this.getCheckedStudentIds(this.localStorageList);
            this.$nextTick(() => {
                this.toggleSelection(this.checkedStudentList);
            });
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值