解决el-table有固定列且有合计行滚动条在固定列处不可选中问题

本文介绍了如何使用Vue的自定义指令解决el-table的滚动条问题,通过隐藏默认滚动条并添加自定义滚动条,配合resizeObserver监听元素变化,实现在表格有滚动需求时动态显示滚动条。

网上搜索的解决方案大都没什么卵用。这里用的vue自定义指令去解决,思路是隐藏自带的滚动条,增加一个自定义滚动条。

我们在指令文件夹directive下新建一个elTableScrollFixed.js文件存放自定义指令代码如下:

// 自定义滚动条方法
function setCustomScrolling(el,tableNode,summaryNode) {
  el.classList.add('custom-scrolling') // 追加一个自定义类,通过这个类在CSS中隐藏原先的滚动条.custom-scrolling .el-table__body-wrapper::-webkit-scrollbar{display: none}
  let bodyWidth = tableNode.offsetWidth + 'px' // 表格宽度
  let tableWidth = tableNode.querySelector('table').offsetWidth + 'px' // 表格内容宽度
  let sunmmaryHeight = summaryNode.offsetHeight?summaryNode.offsetHeight + 'px' : '37px' // 表尾合计行高度
  let removeVirtualNodes = el.querySelectorAll('.virtual-scrolling-box') // 防止重复插入,把已有的虚拟滚动条节点删除掉
  // 遍历这些节点并删除
  if(removeVirtualNodes.length>0){
    removeVirtualNodes.forEach((node)=> {
      if (node.parentNode) {
        node.parentNode.removeChild(node);
      }
    })
  }
  // 追加虚拟滚动条节点
  el.insertAdjacentHTML('beforeend',`<div class="virtual-scrolling-box" style="width: ${bodyWidth};height: 8px;overflow-x: auto;overflow-y: hidden;position: absolute;bottom: ${sunmmaryHeight};left: 0;z-index: 5">
          <p style="width: ${tableWidth};height: 8px;"></p>
          </div>`
  )
  let virtualScrollingBox = el.querySelector('.virtual-scrolling-box') // 获取追加的虚拟滚动条节点
  // 监听虚拟滚动条滚动
  el._virtualScrollingBox_ = virtualScrollingBox
  el._virtualScrollingEvent_ = []
  virtualScrollingBox.addEventListener('scroll', function virtualScrolling() {
    el._virtualScrollingEvent_.push(virtualScrolling) // 事件追加进去解绑时候销毁
    let scrollLeft = virtualScrollingBox.scrollLeft;
    tableNode.scrollLeft = scrollLeft // 滚动距离赋给表格节点
  })
}
export default {
  bind(el, binding, vnode){
    vnode.context.$nextTick(() => {
      let tableNode = el.querySelector('.el-table__body-wrapper.is-scrolling-left') // 表格节点
      let summaryNode = el.querySelector('.el-table__footer-wrapper') // 合计行节点
      // tableNode && summaryNode 成立则认为是有滚动条且有合计行
      if(tableNode && summaryNode){
        setCustomScrolling(el,tableNode,summaryNode) // 设置自定义滚动条
        // 监听元素变化
        const resizeObserver = new ResizeObserver((entries) => {
          tableNode = el.querySelector('.custom-scrolling .el-table__body-wrapper') // 重新获取表格节点
          setCustomScrolling(el,tableNode,summaryNode) // 设置自定义滚动条
        });
        resizeObserver.observe(el)
        // 赋值给el用做销毁
        el._resizeObserver_ = resizeObserver;
      }
    })
  },
  componentUpdated(el, binding, vnode){
    vnode.context.$nextTick(() => {
      vnode.context.$refs['table'].doLayout() // 调用组件上的方法
    });
  },
  unbind(el, binding, vnode){
    // 销毁元素监听
    if (el._resizeObserver_) {
      el._resizeObserver_.disconnect()
      delete el._resizeObserver_
    }
    // 移除滚动条上的监听事件
    if(el._virtualScrollingEvent_ && el._virtualScrollingEvent_.length>0){
      el._virtualScrollingEvent_.forEach(item=>{
        el._virtualScrollingBox_.removeEventListener('scroll', item);
      })
    }
  }
}

PS:尾部合计行高度37px以及滚动条的8px按自己需求更改。

隐藏自身滚动条

在全局css文件中增加如下样式,隐藏el-table自带的滚动条

.custom-scrolling{
  .el-table__body-wrapper::-webkit-scrollbar{display: none}
}
注册指令

在main.js中注册全局指令

import elTableScrollFixed from '@/directive/elTableScrollFixed.js'

Vue.directive('elTableScrollFixed', elTableScrollFixed)
使用指令

在el-table上使用自定义指令

<el-table v-el-table-scroll-fixed >...</el-table>
效果如下

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值