vue+elementui 表格中操作列按钮折叠展开

3,505 阅读1分钟

在开发过程中,遇到表格操作列的按钮比较多,导致表格转行或者操作列占用的width太多的问题,所将这些按钮折叠起来,封装成组件。表格用的是el-table

实现逻辑

  1. 得到表格操作列的宽度,和按钮的个数
  2. 判断:操作列宽度 - (全部按钮的宽度+按钮间隔)< 0
  3. 全部按钮的宽度+按钮间隔超过了操作列的宽度,则实现按钮折叠功能
  4. 遍历按钮,将按钮的宽度和间隔相加等于列表宽的则显示,否则隐藏
  5. 增加触发展开按钮的icon

参数说明

参数名称说明类型
cIndex组件标识,防止父组件中遍历该组件,出现组件相互影响的问题Number
time父组件更新数据或者窗口大小变化时,使用时间戳更新该组件Number

实现效果

1616121005(1).jpg

完整代码

<template>
    <div class="bf-box" :ref="`_bf+${cIndex}`">
        <div :ref="`_bf+${cIndex}_button`">
            <slot></slot>
        </div>
        <el-popover
                popper-class="btn-pop"
                placement="left"
                width="auto"
                trigger="hover">
            <slot></slot>
            <i slot="reference" class="el-icon-more fold-icon" v-show="isFold" ></i>
        </el-popover>
    </div>
</template>

<script>
    export default {
        name: '',
        props:{
            cIndex:{
                type:Number,
                default:0
            },
            time:{
                type:Number,
                default:null
            }
        },
        data(){
            return {
                width:'',
                isFold:false
            }
        },
        watch:{
            // 监听time,重新计算box宽度
            time(val){
                this.domInit();
            }
        },
        mounted(){
            this.domInit();
        },
        methods: {
            domInit(newWidth){

                const children = this.$refs[`_bf+${this.cIndex}_button`].children;
                this.$nextTick(()=>{
                    if(this.isFold || newWidth){
                        for(let k = 0,len = children.length;k<len;k++){
                            let d = children[k];
                            d.style.display = 'inline-block';
                        }
                    }

                    const offsetWidth = newWidth || this.$refs[`_bf+${this.cIndex}`].offsetWidth;
                    const scrollWidth = this.$refs[`_bf+${this.cIndex}`].scrollWidth;

                    this.isFold = offsetWidth < scrollWidth;

                    if(this.isFold){

                        let childrenWidth = [];
                        for(let i = 0,len = children.length;i < len;i++){
                            childrenWidth.push(children[i].offsetWidth)
                        }

                        let wSum = 0,bIndex = 0;
                        for(let i = 0,len = childrenWidth.length;i< len;i++){
                            wSum += childrenWidth[i];
                            i !== 0? wSum += 10 :'';
                            if(wSum < offsetWidth - 14){
                                bIndex = i;
                            }

                        }

                        for(let k = 0,len = children.length;k<len;k++){
                            let d = children[k];
                            k >= bIndex+1 ? d.style.display = 'none':d.style.display = 'inline-block'
                        }
                    }
                })
            },
        }
    }
</script>

<style  lang="scss">
    .bf-box{
        box-sizing: border-box;
        overflow: hidden;
        white-space: nowrap;
        min-width: 50px;
        .fold-icon{
            cursor: pointer;
            position: absolute;
            right: 10px;
            top:calc(50% - 5px);
            color: #1890FF;
        }
    }
     .btn-pop{
        min-width:20px;
        span,div{
            margin-right:5px;
        }
        /deep/ .el-button--text{
                   margin-left:6px;
               }
    }
</style>