vue3+element-plus的table组件实现表格动态渲染、控制显示隐藏列

1,519 阅读2分钟

本文所实现的是最基本的控制显示隐藏表格列,没有其他功能,没有封装成单独的组件。 只为记录自己需要实现的一个小需求,不喜跳过!

直接上效果,看看是否是你所需要实现的效果。

默认展示日期、姓名:

image.png 全部展示:

image.png 上代码(可直接复制):

<template>
    <div>
        <el-button @click="$router.back()">返回</el-button>
        <el-popover placement="bottom" trigger="hover" class="popover">
            <template #reference>
                <el-button class="m-2">Hover to activate</el-button>
            </template>
            <div style="display: flex; justify-content: space-between;align-items: center;">
                <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate"
                    @change="checkAllChangeFn">列展示</el-checkbox>
                <el-button text @click="reset(true)">重置</el-button>
            </div>
            <el-divider></el-divider>
            <el-checkbox-group v-model="checkColumns" @change="changeColumns">
                <el-checkbox v-for="(item, index) in columns" :key="index" :label="item.label"
                    :value="item.prop"></el-checkbox>
            </el-checkbox-group>
            <i class="el-icon-s-tools" slot="reference"></i>
        </el-popover>
        <el-table ref="table" id="table" :key="reload" :data="tableData" border style="width: 100%; margin: 20px 0;">
            <template v-for="item in columns" :key="item.prop">
                <el-table-column v-if="showColumn(item.prop)"  :prop="item.prop" :label="item.label">
                    <template #default="scope">
                        <div>
                            <template v-if="item.prop == 'date'">
                                <span style="color: aqua;">{{ scope.row.date }}</span>
                            </template>
                            <!-- <template v-else>{{ scope.row[item.prop] }}</template> -->
                            <template v-else>{{ scope.row[item.prop] }}</template>
                        </div>
                    </template>
                </el-table-column>
            </template>
        </el-table>
    </div>
</template>

逻辑代码:

<script setup>
import { ref, reactive, nextTick } from 'vue';
const tableData = [{
    date: '2016-05-01',
    name: '王小虎',
    age: 13,
    money: 100
}, {
    date: '2016-05-02',
    name: '王小虎',
    age: 25,
    money: 333
}, {
    date: '2016-05-03',
    name: '王小虎',
    age: 33,
    money: 555
}, {
    date: '2016-05-04',
    name: '王小虎',
    age: 23,
    money: 200
},
{
    date: '2016-05-05',
    name: '王小虎',
    age: 26,
    money: 666
}]

const columns = ref([
    { label: '日期', prop: 'date', isShow: true },
    { label: '姓名', prop: 'name', isShow: true },
    { label: '年龄', prop: 'age', isShow: false },
    { label: '财产', prop: 'money', isShow: false },
])
const checkColumns = ref(['date', 'name']) // 默认显示日期和姓名
const checkAll = ref(false)
const table = ref()
const isIndeterminate = ref(true) // 全选、半选状态
const reload = ref()
// 全选复选框事件
const checkAllChangeFn = (val) => {
    const columnsList = columns.value.map(item => item.prop)
    checkColumns.value = val ? columnsList : []
    if (checkColumns.value.length > 0) {
        checkColumns.value.forEach(item => {
            let current = columns.value.find(i => i.prop == item)
            current.isShow = true;
        })
    } else {
        columns.value.forEach(item => {
            item.isShow = false;
        })
    }
    isIndeterminate.value = false;
}
// 重置,flag: Boolean,全部重置为flag
const reset = (flag) => {
// 重置时恢复之前的数据
    columns.value = [
        { label: '日期', prop: 'date', isShow: true },
        { label: '姓名', prop: 'name', isShow: true },
        { label: '年龄', prop: 'age', isShow: false },
        { label: '财产', prop: 'money', isShow: false },
    ]
    checkColumns.value = ['date', 'name']
    isIndeterminate.value = true;
    // 重新渲染表格
    refreshTable();
}
// 表格列是否显示的方法
const showColumn = (currentColumn) => {
    return columns.value.find(item => item.prop == currentColumn).isShow;
}
/* 选择列 */
const changeColumns = (val) => {
    columns.value.forEach(item => {
        item.isShow = false;
    })
    // columns将val数组存在的值设为true,不存在的设为false
    val.forEach(item => {
        let current = columns.value.find(i => i.prop == item)
        current.isShow = true;
    })
    
    // 判断是否全选
    const checkedCount = val.length
    checkAll.value = checkedCount === columns.value.length
    isIndeterminate.value = checkedCount > 0 && checkedCount < columns.value.length
    // 重新渲染表格
    refreshTable();
}
// 重新渲染表格
const refreshTable = () => {
    reload.value = Math.random() // 解决表格闪烁问题
    nextTick(() => {
        table.value.doLayout()
    })
}
</script>

样式部分:

<style scoped>
/* 分割线 */
.el-divider {
    margin: 10px 0;
}

/* 复选框 */
.el-checkbox-group {
    display: flex;
    flex-direction: column;
}

/* 操作列图标位置 */
.popover {
    display: flex;
    justify-content: flex-end;
    font-size: 30px;
}
</style>

完活,如果能够帮到你,那就再好不过了!

日积硅步,以致千里

dba0be4c-f1c9-4105-9c66-59de8ed45ed9.png