el-table横纵向滚动条固定在可视屏幕内,并自适应分辨率

提示:vue2 + elementUi(适用于table不使用fixed固定列,否则会错位,修复错位方法在下篇)


前言

需求:在使用el-table中,当每页数据过多时浏览器会自动产生纵向滚动条,拖动后表头也看不到了,当表头过长后,也会产生横向滚动条,但是横向滚动条固定在table最底部,不利于操作。

思路:利用自定义指令中的el找出table的dom元素,获取到视窗总高度,获取到table离视窗上面的高度,获取到指令中回传想设置的离底部的高度,计算后获得table高度,并设置css,再通过resize监听动态获取高度,设置高度。


一、使用步骤

1. 在src下面创建一个directive文件夹,再创建index.js和tableHeight.js

tableHeight.js 代码如下:

import {
    addResizeListener,
    removeResizeListener
} from 'element-ui/src/utils/resize-event'

// 设置表格高度
const doResize = async (el, binding, vnode) => {
    // 获取表格Dom对象
    const {
        componentInstance: $table
    } = await vnode
    // 获取调用传递过来的数据
    const {
        value
    } = binding
    // if (!$table.height) {
    //   throw new Error(`el-$table must set the height. Such as height='100px'`)
    // }
    // console.log($table, '$table$table$table$table')
    // 获取距底部距离(用于展示页码等信息)
    const bottomOffset = (value && value.bottomOffset) || 30
    if (!$table) return
    // 计算列表高度并设置
    const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset
    // $table.layout.setMaxHeight(height)
    // $table.layout.setHeight(height)  //头部和底部滚动条不会固定

    //头部和底部顿滚动条会固定但不适用于 使用了fixed固定列的table会错位
    let wrapper = Array.from(el.getElementsByClassName("el-table__body-wrapper"))
      if (wrapper && wrapper.length) {
        wrapper[0].style.height = height + 'px'
        wrapper[0].style.overflow = 'auto'
      }

     $table.doLayout()
    }

export default {
    // 初始化设置
    bind(el, binding, vnode) {
        // 设置resize监听方法
        el.resizeListener = async () => {
            await doResize(el, binding, vnode)
        }
        // 绑定监听方法到addResizeListener
        addResizeListener(window.document.body, el.resizeListener)
    },
    // // 绑定默认高度
    async inserted(el, binding, vnode) {
        await doResize(el, binding, vnode)
    },
    // // 销毁时设置
    unbind(el) {
        // 移除resize监听
        removeResizeListener(el, el.resizeListener)
    }
}

index.js 代码如下:

import tableHeight from './tableHeight'

const install = function (Vue) {
    // 绑定v-adaptive指令
    Vue.directive('tableHeight', tableHeight)
}

if (window.Vue) {
    window['tableHeight'] = tableHeight
    // eslint-disable-next-line no-undef
    Vue.use(install)
}

tableHeight.install = install

export default tableHeight

main.js 中注册指令:

import tableHeight from '@/directive/index.js'
// 表格自适应指令
Vue.use(tableHeight)

最后在el-table 中使用:

  <el-table :data="tableData" v-tableHeight="{bottomOffset: 150}">
     <el-table-column prop="date" label="日期" width="180"></el-table-column>
     <el-table-column prop="name" label="姓名" width="180"></el-table-column>
     <el-table-column prop="address" label="地址"></el-table-column>
     <el-table-column prop="caozuo" label="操作"  fixed="right"></el-table-column>
  </el-table>