0


element ui的table组件横向滚动条始终位于可视区域

需求:表格行数过多,就需要先滚动到表格底部,才能使用横向滚动条,这给用户带来了不便。

思路:在表格内部生成一个自定义横向滚动条,当表格原生的横向滚动条没出现在可视区域范围时,将自定义滚动条调整到视口底部位置,反之隐藏该自定义滚动条。

使用:由于用的是Vue,又涉及到操作Dom,故而把这个功能封装成一个指令,在el-table上添加指令即可。

过程:

main.js(定义全局指令)

//perfect-scrollbar插件的包
import ScrollBar from './direactives/scrollbar'
//对应的css
import 'perfect-scrollbar/css/perfect-scrollbar.css'
//全局指令
Vue.directive('fixed-scroll', ScrollBar)

scrollbar.js

//自定义滚动条
import PerfectScrollbar from 'perfect-scrollbar'
//对应的css
import 'perfect-scrollbar/css/perfect-scrollbar.css'

const updateScrollBar = el => {
  const railX = el.querySelector('.ps__rail-x')
  const _tbody = el //el为表格容器
  // 如果table内部还有滚动条的话需要加上_tbody.scrollTop
  // 视口的高度-tbody基于视口的top值-横向滚动条容器的高度
  const _top = window.innerHeight - _tbody.getBoundingClientRect().top - railX.clientHeight
  railX.style.top = `${_top}px`
  railX.style.opacity = '1'
  railX.style.display = 'block'
}

// 使用插件创建滚动条
const el_scrollBar = el => {
  // 在元素上加点私活,名字随便取,确保不会和已有属性重复即可,取名叫做_ps_
  if (el._ps_ instanceof PerfectScrollbar) {
    el._ps_.update()
  } else {
    // el上挂一份属性
    el._ps_ = new PerfectScrollbar(el, {
      suppressScrollX: false,
      suppressScrollY: true //y方向禁止
    })
  }
}

let isScrolling = false
let _scrollHander = null
let _resizeHander = null

// 自定义vue指令
const directive = {
  // inserted(初次创建dom)获取使用自定义指令处的dom
  inserted(el) {
    el = el.querySelector('.el-table__body-wrapper')
    if (!el) {
      return console.warn('未发现className为el-table__body-wrapper的dom')
    }
    // 判断其样式是否存在position,并且position为"fixed","absolute",或"relative"
    // 如果不符合条件,抛个错误,当然你也可以抛个警告顺便给其position自动加上"relative"
    // 为什么要这样做呢,因为PrefectScrollbar实现原理就是dom注入两个div,一个是x轴一个是y轴,他们两的position都是absolute
    //对css稍有常识的人都知道,absolute是相对于所有父节点里设置了position属性的最近的一个节点来定位的,为了能够正确定位,我们要给其设置position属性
    const rules = ['fixed', 'absolute', 'relative']
    if (!rules.includes(window.getComputedStyle(el, null).position)) {
      console.error(`perfect-scrollbar所在的容器的position属性必须是以下之一:${rules.join('、')}`)
    }
    // el上挂一份属性
    el_scrollBar(el)
    updateScrollBar(el)

    //注册scroll和resize事件
    _scrollHander = () => {
      if (!isScrolling) {
        window.requestAnimationFrame(() => {
          updateScrollBar(el)
          isScrolling = false
        })
      }
      isScrolling = true
    }

    _resizeHander = () => {
      updateScrollBar(el)
    }

    document.addEventListener('scroll', _scrollHander)
    window.addEventListener('resize', _resizeHander)
  },
  // 更新don的时候
  componentUpdated(el, binding, vnode) {
    const { expression } = binding

    el = el.querySelector('.el-table__body-wrapper')
    if (!el) {
      return console.warn('未发现className为el-table__body-wrapper的dom')
    }

    const handler = () => vnode.context[expression].apply()

    // vnode.context其实就是vue实例,这里其实无需实例也直接用vue的静态方法
    vnode.context.$nextTick(() => {
      try {
        el_scrollBar(el)
        updateScrollBar(el)
        if (expression) {
          handler()
        }
      } catch (error) {
        console.error(error)
      }
    })
  },
  unbind() {
    document.removeEventListener('scroll', _scrollHander)
    window.removeEventListener('resize', _resizeHander)
  }
}

export default directive

组件中使用

<el-table :data="deliverTable" border highlight-current-row :header-cell-style="{ background: '#eef1f6', color: '#606266' }" v-loading="listLoading" v-fixed-scroll>

注意:如果表格有固定列,需要给横向滚动条设置高于固定列的层级z-index

App.vue

.ps__rail-x {
  display: block;
  z-index: 999; 
}

实现:当表格底部不在可视区域范围内时,横向滚动条固定在视口底部的位置。

参考:vue中使用perfect-scrollbar

标签: vue.js 前端 elementui

本文转载自: https://blog.csdn.net/qq_56162766/article/details/130240104
版权归原作者 能当饭吃么你说_ 所有, 如有侵权,请联系我们删除。

“element ui的table组件横向滚动条始终位于可视区域”的评论:

还没有评论