vxe-table复选框翻页选中问题及其搜索后去除选中、全选问题处理

2,766 阅读2分钟

需求分析:

  1. 表格的复选框要能够跨页选择,之前勾选了的页面需要保留数据;
  2. 最上方的全选是表示选择了后端返回的total的全部数据(并不是当前页的全部数据),表格标题的最上方勾选才是勾选的当前页的全部数据。
  3. 图中的批量操作成功后(如下图的批量启动/停用/推送),要使表格清除所有选中内容,但是所显示的表格数据是在批量操作前的数据。(因为头部第二栏中有多个筛选条件用来筛选表格数据。所以这里在批量操作后不用刷新到表页面的初始状态)

image.png

技术分析:

  1. vxe-table中需要row-id="id"标识,并且设置:checkbox-config="{ reserve: true,}"保存到当前页选中的数据;
  2. 用动态:key去更新表格,刷新表格勾选的checkbox状态显示(因为如果是做的翻页要保留当前页勾选的数据的话根据官方提供的方法是只能清除当前页的状态,但是页面显示checkbox又还是勾选状态)
  3. 用clearCheckboxRow()方法清除checkbox勾选的状态;
  4. 当要全选所有数据时,除了把接口返回的所有总数count的表格数据全部展示在表格中要表示勾选状态外,要全部得到勾选的所有数据,我们在这里是实现上默认用一页查出所有数据。

主要代码实现:

        <!-- 展示表格,先展示一个表格 -->
        <div class="tableSty">
            <vxe-table ref="multipleTableRef" :data="agent_info" style="width: 100%" row-id="findex"
                :key="multipleTableKey" hight="auto" :checkbox-config="{ reserve: true,}"
                :column-config="{ resizable: true, minWidth: 100 }" :row-config="{isHover: true}" show-overflow
                show-header-overflow @checkbox-change="handleSelectionChange" @checkbox-all="selectAllChangeEvent"
                :tooltip-config="{theme:'light',enterable:true}" @cell-dblclick="celldblclick" :filter-config="{remote:
                    true}" @filter-change="filterChange">
                <vxe-column type="checkbox" align="center" width="50" />
                <!-- <vxe-column field="findex" title="findex" /> -->
                <vxe-column field="fserver_host" title="机器IP" />
                <vxe-column field="fagent_name" title="agent_name" />
                <vxe-column field="fagent_version" title="版本号" />
                <vxe-column field="fmd5" title="md5" width="300" />
                <vxe-column field="fupdate_flag" title="更新状态" />
                <vxe-column field="fstatus" title="agent状态" :filters="[{label:'online',value:'online'
            },{label:'offline',value:'offline'}]">

                    <template #default="{ row }">
                        <div class="vxe-column-row">

                            <div class="point-state" :class="fstatusClass(row.fstatus)" :style="
                            row.fstatus == 'online'
                              ? { opacity: changeOpcity1 }
                              : { opacity: changeOpcity }
                          ">
                            </div>

                            <span>{{row.fstatus}}</span>
                        </div>

                    </template></vxe-column>>
                <vxe-column field="fswitch" title="开关" :filters="[{label:'ON',value:'ON'
                    },{label:'OFF',value:'OFF'}]" />
                <vxe-column field="fagent_time" title="agent启动时间" />
            </vxe-table>


        </div>

 <div class="page">
            <el-pagination v-model:currentPage="currentPage" v-model:page-size="pageSize" small
                :page-sizes="[10,20, 40, 80, 100,10000]" layout="total, sizes, prev, pager, next, jumper"
                :total="pageTotal" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
        </div>
        
      <script setup>
 引入
  import { ref, computed, reactive, toRefs, onMounted } from 'vue'
    import { sync_info, agent_switch, server_update, agent_update, agent_name, add_servers, agent_add } from '@/api/matrix';
    import { useStore } from 'vuex';
    import XEUtils from 'xe-utils'
    import { ElNotification, ElMessage } from 'element-plus'
      
  // 参数定义
    const server_host = ref('')
    const md5 = ref('')
    const agent_name1 = ref('')
    const diff = ref(false)
    const multipleTableKey = ref(100)
    const multipleTableRef = ref(null)
    const agent_info = ref([])
    const selectionRows = ref([])
    const selectedRowKeys = ref([])
    const currentPage = ref(1);
    const pageSize = ref(20)
    const pageTotal = ref(20)
    const agent_name_list = ref([])
    const checkAll = ref(false)
    const agent_nameFilter = ref([])
    const statusFilter = ref([])
    const switchFilter = ref([])

//涉及到的方法
const search = () => {
        ++multipleTableKey.value;
        selectionRows.value = [];
        selectedRowKeys.value = [];
        const $table = multipleTableRef.value
        if ($table) {
            $table.clearCheckboxRow()
        }
        setTimeout(() => {
            getTable();
        }, 50)


    }
    const refreshTable = () => {
        ++multipleTableKey.value;
        selectionRows.value = [];
        selectedRowKeys.value = [];
        const $table = multipleTableRef.value
        if ($table) {
            $table.clearCheckboxRow()
        }

    }
    
    const getTable = () => {
        sync_info({
            page: currentPage.value,
            size: pageSize.value,
            server_host: server_host.value,
            md5: md5.value,
            agent_name: agent_name1.value,
            diff: diff.value ? 1 : 0,
            status: statusFilter.value.join(','),
            switch: switchFilter.value.join(','),

        }).then(res => {
            if (res.code == 200) {
                agent_info.value = res.data.results;
                pageTotal.value = res.data.count;
                controlLight();

            }

        })
    }

    const handleSizeChange = (val) => {
        pageSize.value = val;
        getTable();
    }
    const handleCurrentChange = (val) => {
        currentPage.value = val;
        getTable();
    }
    
    //这里写入一个批量操作为例
      // 批量推送
    const multiUpdate = () => {
        ElMessageBox.prompt('请输入要批量推送的数目值(整数):', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            inputPlaceholder: '请输入跟你选择的数目相匹配的数值...',
            inputType: 'number',
            inputValidator: (val) => {
                if (val == selectionRows.value.length) {
                    return true
                } else {
                    return false
                }

            },
            inputErrorMessage: '请输入跟你选择的数目相匹配的数值',
            center: true,
        })
            .then(({ value }) => {
                const findexMap = selectionRows.value.map(item => {
                    return item.findex
                })

                server_update({
                    findex: findexMap.join(),

                }).then(res => {
                    if (res.code == 200) {
                        ElNotification({
                            title: '批量推送提示',
                            message: res.data,
                            type: 'success',
                        })
                        setTimeout(() => {
                            refreshTable();
                        }, 100)

                    } else {
                        ElNotification({
                            title: '批量推送提示',
                            message: res.data,
                            type: 'error',
                        })
                    }
                })

            }).catch(() => {

            })

    }
<script>