vue3中el-checkbox实现在el-table多行全选功能

 0 0条评论

在项目中,权限管理中需要使用到多个checkbox,每一行都需要单独的实现全选功能,如果是单独的一行数据,相信大家都会,非常简单,但是这是在多行数据里面,实现起来就有点麻烦,话不多说,先看最终实现效果。


首先定义state

const state = reactive({
    isShow: false, // dialog是否显示
    systemrouter: [], // 系统所有路由
    selectedrouter: [], // 选中的路由
    routerSearch: '', // 搜索路由
    checkAll: [], // 每一行是否全选
    ID: '' // 角色ID
    })

其中systemrouter返回的数组数据大致如此:

 "data": [
        {
            "model": "user",
            "methods": [
                "post",
                "delete",
                "put",
                "get"
            ],
            "des": "管理用户"
        },
        {
            "model": "catalog",
            "methods": [
                "post",
                "delete",
                "put",
                "get"
            ],
            "des": "文章目录"
        }
    ]

而selectedrouter是最终提交给服务器的数据,数据所需要的数据格式大致如此,与systemrouter就是少了des属性:

    "routerList":[
        {
            "model": "user",
            "methods": [
                "post",
                "delete",
                "put",
                "get"
            ]
        },
        {
            "model": "catalog",
            "methods": [
                "post",
                "delete",
                "put"
            ]
        }]
    }

之后看一下vue代码,vue代码相对比较简单,核心就在于功能这一列。

scope.$index可以获得当前的行号,然后使用el-checkbox-group组件,其中v-model指定selectedrouter[scope.$index].methods这一行,即可以绑定selectedrouter当前行的数据,子组件el-checkbox展示systemrouter当前行methods数组中所有属性。

而全选的checkbox,需要绑定自定义的一个数据checkAll的当前行。

<el-table :data="systemrouter.filter(data => !routerSearch 
    || data.model.toLowerCase().includes(routerSearch.toLowerCase())
    || data.des.toLowerCase().includes(routerSearch.toLowerCase()))" lazy ref="refRouter" stripe border>
    <el-table-column width="120" prop="model" label="模块">
        <template v-slot="scope">
            {{scope.row.model}}
        </template>
    </el-table-column>
    <el-table-column prop="des" label="描述" width="100px">
    </el-table-column>
    <el-table-column align="right" label="功能">
        <template #default="scope">
            <el-checkbox-group class="group" @change="handleCheckedRouterChange(scope.$index)"
                v-model="selectedrouter[scope.$index].methods">
                <el-checkbox class="checkbox" :label="method" v-for="method in scope.row.methods"
                    :key="method+Math.random()">
                    {{getMethodsName(method)}}
                </el-checkbox>
            </el-checkbox-group>
            <el-checkbox v-model="checkAll[scope.$index]"
                @change="val=>handleCheckAllChange(val,scope.$index) ">全选
            </el-checkbox>
        </template>
    </el-table-column>
</el-table>

当数据首次展示时候,首先服务器获得systemrouter数据,然后循环该数据,将model和methods属性push到selectedrouter中,其中methods初始为空。

之后再从服务器或许routerlist数据,即选中的数据,然后再次循环该数组,如果有methods数据,则重新赋值。

最后判断methds是否包括全部,如果是则对应的checkAll的该行数据赋值true,代码如下:

const show = (id) => {
    state.isShow = true
    state.ID = id
    AJGetSystemRouter().then(res => {
        state.systemrouter = res.data
        // 循环所有系统router,赋值给selectedrouter并且默认methods为空
        for (let route of state.systemrouter) {
            state.selectedrouter.push({
                model: route.model,
                methods: []
            })
            // 默认全选是false
            state.checkAll.push(false)
        }
        AJGetRoleByID(id).then((res) => {
            const routerList = res.data.routerList
            // 循环该角色拥有的router,使selectedrouter中有此model的记录,赋值methods
            for (let i = 0; i < routerList.length; i++) {
                state.selectedrouter.find(route => {
                    return route.model === routerList[i].model
                }).methods = routerList[i].methods
                // 如果routerList中的methods包括全部,则全选按钮为true
                if (routerList[i].methods.length === state.systemrouter[i].methods
                    .length) {
                    state.checkAll[i] = true
                    }
            }
        })
    })
}

以下是el-checkbox-group的change事件,传入当前行的index,判断全选按钮是否选中。

// 当改变某一行选择时,如果长度是最大值,则全选按钮为true,否则为false
const handleCheckedRouterChange = (index) => {
    state.checkAll[index] = (state.systemrouter[index].methods.length === state.selectedrouter[
        index].methods.length)
}

以下是权限el-checkbox的changge事件

// 点击全选按钮后,使得当前行的selectedrouter等于当前行的systemrouter的methods
const handleCheckAllChange = (val, index) => {
    state.selectedrouter[index].methods = val ? state.systemrouter[index].methods : []
}

最后提交时,需要过滤一下selectedrouter数据,因为此数据中包含很多methods为空的行,但是服务器不允许这样的数据。

const handleDialogOK = () => {
    // 过滤掉selectedrouter中methods为空的数据
    const list = state.selectedrouter.filter(item => {
        return item.methods.length != 0
    })
    // 使用list提交到服务器
}

至此功能全部实现。

本文作者:双黑

版权声明:本站文章欢迎链接分享,禁止全文转载!

游客