el-table列的显示与隐藏

  • 需求:实现 表字段的显示与隐藏。
  • 效果图 在这里插入图片描述

代码实现

写在前面

  • 首先 我部分字段有自定义的排序逻辑,和默认值或者 数据的计算 所以是不能简单的使用 v-for 循环column 。
  • 然后 我需要默认展示一部分字段,并且 当表无数据时 提示不能 显示隐藏 字段。
  • 做一个类表单的设计,在提交的时候才做数据变更,并且添加搜索。

功能实现

因为每个字段的处理不尽相同,所以我采用 v-if 进行控制(注意 v-if 对dom的开销较大,⚠️多字段)。

  1. 先设置固化数据
  2. 设置字段信息
  3. 添加按钮和 el-popover
  4. 相关函数添加和调试
  5. 添加搜索框
  6. 函数添加
  1. 先设置固化数据
data() {
	return {
	    // 搜索框的输入
	    popoverSearchQuery: '',
	    // el-table 的加载值
	    reload: 1,
	    // 是否打开 el-popover
	    popoverVisible: false,
	    // 选中的列对象数组
	    selectColumns: [], 
	    // 未选中的列对象数组
	    unSelectColumns: [], 
	    // checkbox 的model
	    tempSelectColumns: [], 
	    // 固化的表字段,默认值设置
	    columnSetting: [
	        // {prop: 'userChineseName', label: '人员', isShow: true},
	        {prop: 'onDutyDays', label: '实际出勤天数', isShow: true},
	        {prop: 'avgDutyMinutesPerDutyDay', label: '平均每日出勤时长(小时)', isShow: true},
	        {prop: 'avgTaskMinutesPerDutyDay', label: '平均每日任务时长(小时)', isShow: true},
	        {prop: 'taskNum', label: '任务数', isShow: true},
	        {prop: 'bugOverview', label: '产出Bug', isShow: true},
	        {prop: 'caseOverview', label: '产出Case', isShow: true},
	        {prop: 'codeOverview', label: '产出代码', isShow: true},
	        {prop: 'userGroupName', label: '当前所属团队', isShow: false},
	        {prop: 'userLevel', label: '人员职级', isShow: false},
	        {prop: 'theoreticalOnDutyDays', label: '应出勤天数', isShow: false},
	        {prop: 'otDays', label: '加班天数', isShow: false},
	        {prop: 'absenteeismDays', label: '旷工天数', isShow: false},
	        {prop: 'afterPunchDays', label: '补卡天数', isShow: false},
	        {prop: 'tagCount', label: '标注件数', isShow: false},
	        {prop: 'rewardTagCount', label: '悬赏数', isShow: false}
	    ]
	}
}
  1. 设置字段信息
    要明确一点:要不要有默认展示字段(即:当所有字段不勾选时,展示什么字段数据)
<!-- 人员默认展示,即对该字段不做判断 -->
<el-table-column
    label="人员"
    width="200px"
    align="center"
    fixed="left"
>
    <template slot-scope="scope">
        {{ `${scope.row.userChineseName}(${scope.row.username})` }}
    </template>
</el-table-column>

<!-- v-if实现字段的显示隐藏 参数为prop或者唯一值即可 -->
<el-table-column
    v-if="showColumn('onDutyDays')"
    label="实际出勤天数"
    align="center"
    prop="onDutyDays"
    sortable="custom"
    min-width="80"
>
<template slot-scope="scope">
        <div>
            {{ scope.row.onDutyDays }}
        </div>
    </template>
</el-table-column>
  1. 添加页面和触发按钮(搜索框和 checkbox)
<!--添加字段筛选-->
<div>
    <el-button
        type="text"
        plain
        class="custom-button"
        style="border: none"
        icon="el-icon-s-tools"
        size="mini"
        @click="openSelectPopover"
    >筛选字段</el-button>
    <el-popover
        v-model="popoverVisible"
        placement="bottom-end"
        trigger="click"
        class="my-popover"
    >
        <!-- 搜索 -->
        <!-- 搜索框容器,使用position: sticky来使其在页面滚动时保持在顶部 -->
        <div class="search-bar-container" style="position: sticky; top: 0; z-index: 10; background-color: white;">
            <el-input
                v-model="popoverSearchQuery"
                suffix-icon="el-icon-search"
                placeholder="搜索"
                clearable
                @suffix-click="handlePopoverSearchQuery"
            ></el-input>
        </div>
        <div class="columns-filter">

            <!-- 已选中的项 -->
            <div v-if="selectColumns.length > 0">
                <h3 style="margin-top: -10px;color: #d76969;">已选择</h3>
                <div v-for="(column, index) in selectColumns" :key="column.prop">
                    <el-checkbox
                        v-model="tempSelectColumns"
                        :label="column"
                        :value="column"
                        @change="selectHandleCheckboxChange(column)"
                    >{{ column.label }}</el-checkbox>
                </div>
                <hr> <!-- 已选中与未选中之间的横线 -->
            </div>
            <!-- 未选中的项 -->
            <div v-for="(column, index) in unSelectColumns" :key="column.prop">
                <el-checkbox
                    v-model="tempSelectColumns"
                    :label="column"
                    :value="column"
                    @change="selectHandleCheckboxChange(column)"
                >{{ column.label }}</el-checkbox>
            </div>
            <br>
            <div slot="footer" style="display: flex; justify-content: center;">
                <el-button
                    icon="el-icon-close"
                    size="mini"
                    @click="popoverVisible = false"
                >取 消</el-button>
                <el-button
                    size="mini"
                    icon="el-icon-check"
                    type="primary"
                    @click="confirmSelection"
                >确 定</el-button>
            </div>

        </div>
    </el-popover>
</div>

<!--样式 -->
<style lang="scss" scoped>
// 按钮样式设计, 右上角
.custom-button{
  float: right;
  margin-right: 50px;
  margin-top: -6px;
  font-size: 13px;
}
// 鼠标悬浮 改变背景色
.custom-button:hover {
  background-color: transparent;
  color: #ad64a4;
}
// popover位置设置
.my-popover {
  float: right;
  margin-right: 130px;
  margin-top: 20px;
}
// popover 内部设置最高和滚动条
.columns-filter {
  max-height: 270px;
  overflow-y: auto;
  padding: 10px;
  font-size: 15px;
}
</style>
  1. 相关函数添加和调试
// input 值发生变动就进行搜索
watch: {
    popoverSearchQuery(newVal) {
        if (!newVal) {
            this.resetColumns();
        }
        else {
            this.filterColumns();
        }
    }
}
// 初始化
created() {
    this.initColumn();
},
methods: {
	// 搜索相关-前端实现
    handlePopoverSearchQuery() {
        this.filterColumns();
    },
    filterColumns() {
        this.selectColumns = this.columnSetting.filter(column => column.isShow && column.label.includes(this.popoverSearchQuery));
        this.unSelectColumns = this.columnSetting.filter(column => !column.isShow && column.label.includes(this.popoverSearchQuery));

        if (!this.popoverSearchQuery) {
            this.resetColumns();
        }
    },
    resetColumns() {
        this.selectColumns = this.columnSetting.filter(column => column.isShow);
        this.unSelectColumns = this.columnSetting.filter(column => !column.isShow);
    },
    // 初始化 给 选中和未选中赋值
    initColumn() {
        this.selectColumns = this.columnSetting.filter(column => column.isShow);
        this.unSelectColumns = this.columnSetting.filter(column => !column.isShow);
        // 设置checkbox中值为已选中的值
        this.tempSelectColumns = [...this.selectColumns];
    },
    // 计算是否需要展示
    showColumn(currentColumn) {
        return this.columnSetting.find(item => item.prop === currentColumn).isShow;
    },
    // onclick 按需 添加逻辑,如果不需要 点确定再触发方法 就可以将  confirmSelection 拿到 该函数中。
    selectHandleCheckboxChange(column) {
    },
    // 打开|关闭 popover
    openSelectPopover() {
        if (this.gridData.length < 1) {
            Message.warning('当前列表数据,暂无法使用筛选功能~ ');
            return;
        }
        if (this.popoverVisible) {
            this.popoverVisible = false;
        }
        else {
            this.popoverVisible = true;
            this.popoverSearchQuery = '';
        }
    },
    // 触发数据 处理 
    confirmSelection() {
        const unSelectColumns = this.columnSetting.filter(col =>
            !this.tempSelectColumns.some(tsc => tsc.prop === col.prop)
        ).map(col => ({...col, isShow: false}));

        this.unSelectColumns = unSelectColumns;
        // 更新tempSelectColumns的isShow
        this.tempSelectColumns.forEach(tsc => {
            tsc.isShow = true;
        });
        this.selectColumns = this.tempSelectColumns;
        // 更新columnSetting
        this.columnSetting = [...this.tempSelectColumns, ...unSelectColumns];
        // 这里可以添加额外的处理逻辑,比如发送请求等
        this.popoverVisible = false;
    }
}

fix:

提交 确定 之后 表格会闪烁一下 再显示字段。这是因为dom要重新加载 被销毁的元素。
解决方案 :

el-table 添加 :key=“reload”

<el-table
    :key="reload"
    
    style="margin-right: 30px"
    :header-row-style="{
        background: '#f5f5f5',
        padding: '0',
        color: 'black',
        fontSize: '12px',
    }"
    
>
</el-table>
watch: {
    columnSetting (newVal) {
        // 解决表格闪烁
        this.reload = Math.random();
    }
}

end

  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值