el-table 右侧固定操作列动态改变宽度

image.png

如上图,这是很常见的element-ui里的table表格

有时候右侧固定操作列按钮很多,而且要根据不同的条件进行显示隐藏,当我们给操作列固定宽度的时候,就会出现明明一页表格里的按钮就1-2个,但是空白贼大,甲方不能忍,只好优化一下咯

干起来!

具体实现:
实现原理: 使用vue的指令实现 + 在对应的页面增加了些配置代码

你可以狠狠的戳这个demo 链接查看效果:
注:可能会出现element-ui 或者Vue 链接下载一时半会加载不出来的情况,等待等待,或者刷新几次再看效果

demo 例子

动图无法展示出来,所以还是访问上述例子,更直接体会效果!


笑.gif
js 改动:
directives: {  // 在该模版任意元素上使用
        'fit-columns': {
            inserted: function () {
                setTimeout(() => {
                    console.log(888)
                    adjustColumnWidth()
                }, 100)
            }
        }
    },

///....一堆其他代码
let hash = {}

// 设置操作列的宽度
function handleWidth({ table, resValue }) {
    if (!table) { return }
    const list = table.querySelectorAll(`col`)
    const len = list.length
    let gutterIndex = -1
    list.forEach((el, index) => {
        const isHasGutter = el.getAttribute('name').includes(`gutter`)
        if (isHasGutter) {
            gutterIndex = index
        }
    })

    const idx = (gutterIndex !== -1) ? len - 2 : len - 1 // 有gutter改变的gutter的前一列,反之是最后一列
    list[idx].setAttribute('width', resValue)

    // 设置cell的长度
    table.querySelectorAll(`td.el-table__cell > .cell`).forEach(el => {
        el.style.width = `${resValue}px`
    })
}

function getBtnSumWidth(ele) {
    let sumWidth = 0
    const arr = []
    const len = ele.length
    for (let i = 0; i < len; i++) {
        if (ele[i].style.display !== 'none') {
            const w = ele[i].clientWidth
            sumWidth += w
        }
        arr.push(sumWidth)
    }
    // 加上btn之间的margin间隔
    return arr
}

// 获取操作列的宽度
function getOpeColumnWidth() {
    const btnDivEle = document.querySelectorAll('.specificalTable  .el-table__fixed-right  .btnWrap ')
    let arr = []
    for (let i = 0; i < btnDivEle.length; i++) {
        const btnList = btnDivEle[i].children
        arr = [...arr, ...getBtnSumWidth(btnList)]
    }

    const sum = arr.length ? Math.max(...[...new Set(arr)]) : 0
    return sum
}

const PADDING = 56  // 注意这个PADDING不是固定的,根据项目的情况,调整到一个最合适的值

// 调整操作列的宽度
function adjustColumnWidth(currPage = 1) {
    if (currPage === 1) {
        hash = {}
    }
    const headerTable = document.querySelector('.specificalTable .el-table__header-wrapper > .el-table__header')
    const normalTableBody = document.querySelector('.specificalTable .el-table__body-wrapper > .el-table__body')

    const fixedTableBody = document.querySelector('.specificalTable .el-table__fixed-body-wrapper > .el-table__body')
    const fixedRightTable = document.querySelector('.specificalTable .el-table__fixed-right')
    const fixedHeaderTable = document.querySelector('.specificalTable .el-table__fixed-header-wrapper > table')

    const operateColumnWidth = hash[currPage] ? hash[currPage] : getOpeColumnWidth()
    const resValue = operateColumnWidth + PADDING
    hash[currPage] = operateColumnWidth
    fixedTableBody && (fixedTableBody.style.width = `${resValue}px`)
    fixedRightTable && (fixedRightTable.style.width = `${resValue}px`)
    // 设置操作列的宽度,包含col的宽度,cell的宽度,有4个table:表头,表体,fixed表头,fixed表体
    handleWidth({ table: headerTable, resValue })
    handleWidth({ table: normalTableBody, resValue })
    handleWidth({ table: fixedHeaderTable, resValue })
    handleWidth({ table: fixedTableBody, resValue })
}

上述指令做了啥事??

疑惑.jpg

我们一一解释:

  • hash 的作用是为了缓存每页最大的操作列宽度作为该页操作列的宽度值
  • 当currPage=1时,为啥hash重置为{}? 这是因为当页面有查询等操作时,是从第一页重新开始查,此时操作列的宽度也得动态变化,得重置重新计算
  • element-table实际上有fixed属性时,表格实际上是四个table渲染 展示出来的效果,所以对四个table做了操作(关于四个table 请自行查阅相关资料了解)
  • 使用querySelector时,要对该页面的table设置独特的class属性,比如这里是specificalTable 类名
  • getOpeColumnWidth 获取操作列里的按钮相加的最大宽度
  • handleWidth 动态设置操作列的宽度
  • 当然你也可以选择将指令提取成一个文件,注册成全局指令,进行使用

再看其他代码:

mounted() {
        window.addEventListener('resize', this.handleColumnWidthAndDoLayout, true)
 },
 beforeDestroy() {
        window.removeEventListener('resize', this.handleColumnWidthAndDoLayout, true)
        clearTimeout(this.timer)
        this.timer = null
 },
watch: {
        tableData: {
            handler(val) {
                this.handleColumnWidthAndDoLayout()
            },
            deep: true
        },
 },
methods: {
    handleColumnWidthAndDoLayout() {
            const that = this
            this.loading = true
            this.timer = setTimeout(() => {
                adjustColumnWidth()
                this.loading = false
            }, 800)
        }
}

上述又做了啥事??

疑惑.jpg

我们一一解释:

  • watch table变化,去调整操作列宽度(即页数发生变化or 页面查询)
  • 页面 resize时,动态的调整操作列的宽度, 注意离开页面前,移除对应的监听
vue 文件改动

table vue里增加了4点

  • table 增加class为 specificalTable
  • v-fit-columns 指令
  • v-loading 加载指令(element-ui高版本本身拥有的属性)
  • 操作列的div增加了 class="btnWrap"

为啥要做这些操作呢?

  • 增加了v-loading="loading",因为每次动态计算时操作列的宽度有短时间的闪动,增加table loading 让用户不要太关注这点
  • 操作列的div增加了 class="btnWrap" , 为了让钩子函数选择器获取对应table准确,否则用单一的el.table这种,会影响其他tab 页面的table 列变化
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容