ElementPlus 表格的全选、跨页复选

1,554 阅读2分钟

一、全选 (未包含批选复选)

全选.gif

场景:
1、点击全选的时候,当前页面数据全部选中,切换页码时,所选择的页面数据全部选中
2、当前页面选择的数据条数不等于当前页面全部数据条数时,为非全选,反之全选

HTML片段

<template>
    <div>
        <el-table
            :data="tableData"
            :loading="loading"
            border
            ref="tableRef"
            @select="handleSelect"
        >
            <el-table-column type="selection" width="55"></el-table-column>
            <el-table-column prop="name" label="姓名" align="center" />
            <el-table-column prop="sex" label="性别" align="center" />
            <el-table-column prop="hobby" label="爱好" align="center" />
            <el-table-column prop="age" label="年龄" align="center" />
        </el-table>
        <div style="margin-top: 20px; text-align: left">
            <el-button v-if="!isAll" type="primary" @click="handleAllChoose"
                >全选</el-button
            >
            <el-button v-else type="primary" @click="handleNoChoose"
                >取消全选</el-button
            >
        </div>
        <el-pagination
            style="margin-top: 20px"
            :current-page="current"
            :page-size="size"
            :page-sizes="[10, 20, 30, 40]"
            background
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
        />
    </div>
</template>

实现场景代码

const handleSelect = (rows) => {
    selectRows.value = rows.map((it) => it.id);
    if (isAll.value) {
        if (selectRows.value.length != tableData.value.length) {
            isAll.value = false;
        }
    } else {
        if (selectRows.value.length == tableData.value.length) {
            isAll.value = true;
        }
    }
};

const handleAllChoose = () => {
    isAll.value = true;
    tableRef.value.toggleAllSelection();
};

const handleNoChoose = () => {
    isAll.value = false;
    tableRef.value.clearSelection();
};

const handleSizeChange = (pageSize) => {
    loading.value = true;
    // 模拟接口请求
    if (pageSize > 10) {
        tableData.value = data1.concat(data2);
    } else {
        if (current.value == 1) {
            setTimeout(() => {
                tableData.value = data1;
                loading.value = false;
            }, 200);
        } else {
            setTimeout(() => {
                tableData.value = data2;
                loading.value = false;
            }, 200);
        }
    }
    if (isAll.value) {
        setTimeout(() => {
            tableRef.value.toggleAllSelection();
        }, 300);
    }
    size.value = pageSize;
};

const handleCurrentChange = (pageCurrent) => {
    loading.value = true;
    // 模拟接口请求
    if (pageCurrent == 1) {
        setTimeout(() => {
            tableData.value = data1;
            loading.value = false;
        }, 200);
    } else {
        setTimeout(() => {
            tableData.value = data2;
            loading.value = false;
        }, 200);
    }
    if (isAll.value) {
        setTimeout(() => {
            tableRef.value.toggleAllSelection();
        }, 300);
    }
    current.value = pageCurrent;
};

二、跨页批选复选

复选.gif

实现场景代码:

const handleSelect = (rows) => {
    selectRows.value = rows.map((it) => it.id);
    if (isAll.value) {
        if (selectRows.value.length != tableData.value.length) {
            isAll.value = false;
        }
    } else {
        if (saveCoachData.value.length == tableData.value.length) {
            isAll.value = true;
        }

        if (saveCoachData.value.length) {
            // 先在缓存数据中获取检索是否有之前勾选过的数据
            // 如果在后续操作中 勾选的数据数量比之前少 说明做了取消勾选部分数据,反之添加了部分数据
            const isExistArr = [];
            saveCoachData.value.map((it) => {
                const index = tableData.value.findIndex((i) => i.id == it);
                if (index > -1) {
                    isExistArr.push(it);
                }
            });
            // 取消勾选部分数据
            if (isExistArr.length > selectRows.value.length) {
                isExistArr.map((it) => {
                    const index = saveCoachData.value.findIndex((i) => i == it);
                    if (selectRows.value.indexOf(it) < 0) {
                        saveCoachData.value.splice(index, 1);
                    }
                });
            }
            // 额外勾选选择部分数据
            if (isExistArr.length < selectRows.value.length) {
                selectRows.value.map((it) => {
                    if (isExistArr.indexOf(it) < 0) {
                        saveCoachData.value.push(it);
                    }
                });
            }
        }
    }
};

const handleAllChoose = () => {
    isAll.value = true;
    tableRef.value.toggleAllSelection();
};

const handleNoChoose = () => {
    isAll.value = false;
    tableRef.value.clearSelection();
};

const fetchData = () => {
    if (size.value > 10) {
        tableData.value = data1.concat(data2);
    } else {
        if (current.value == 1) {
            setTimeout(() => {
                tableData.value = data1;
                loading.value = false;
            }, 200);
        } else {
            setTimeout(() => {
                tableData.value = data2;
                loading.value = false;
            }, 200);
        }
    }
    if (isAll.value) {
        setTimeout(() => {
            tableRef.value.toggleAllSelection();
        }, 300);
    } else {
        setTimeout(() => {
            if (!saveCoachData.value.length) {
                saveCoachData.value = selectRows.value;
            }
            if (saveCoachData.value.length) {
                saveCoachData.value.map((it) => {
                    const obj = tableData.value.find((i) => i.id == it);
                    if (obj) {
                        setTimeout(() => {
                            tableRef.value.toggleRowSelection(obj);
                        }, 300);
                    }
                });
            }
        }, 300);
    }
};

const handleSizeChange = (pageSize) => {
    loading.value = true;
    size.value = pageSize;
    // 模拟接口请求
    fetchData();
};

const handleCurrentChange = (pageCurrent) => {
    loading.value = true;
    current.value = pageCurrent;
    // 模拟接口请求
    fetchData();
};

注意:

对于该场景在实现过程中,遇到两个小问题:
1、对于表格的勾选事件,需要使用select事件,不可以使用selection-change,因为在每次加载数据的时候,会执行toggleRowSelection事件,会触发,这个时候selectRows选中的数据就会实时的发生变化,无法捕捉去判断本次操作是取消勾选了还是添加勾选项了。
2、要在数据获取后在进行相关的复选操作,否则有可能因为异步的问题导致获取到的数据是上次展示的页面数据。