Vue2+Element-ui实现el-table表格自适应高度

效果图


新建指令

javascript 复制代码
Vue.directive('height', {
  inserted(el, _binding, vnode) {
    const paginationRef = vnode.context.$refs.paginationRef
    const calculateHeight = () => {
      const windowHeight = window.innerHeight
      const topOffset = el.getBoundingClientRect().top
      const otherElementsHeight = 40 
      let paginationHeight = 0
      if (paginationRef && paginationRef.totalPage) {
        paginationHeight = 55
      }
      el.style.height = `${
        windowHeight - topOffset - otherElementsHeight - paginationHeight
      }px`
    }
    const debouncedCalculateHeight = _.debounce(calculateHeight, 500)
    debouncedCalculateHeight()
    window.addEventListener('resize', debouncedCalculateHeight)
    el.__vueHeightDirective__ = debouncedCalculateHeight
  },
  unbind(el) {
    window.removeEventListener('resize', el.__vueHeightDirective__)
    delete el.__vueHeightDirective__
  }
})

页面使用

1:el-table外层嵌套div,加指令v-height

2:el-table设置height=100%

javascript 复制代码
<div v-height>
   	<el-table height="100%">
		</el-table-column>
	</el-table>
</div>

注意,重点!

1:指令这一行 const paginationRef = vnode.context.$refs.paginationRef
用来判断是否显示分页器,所以如果有分页器需要在分页器增加ref,如下:

javascript 复制代码
<el-pagination ref="paginationRef">
</el-pagination>

2:至于这一行 paginationRef.totalPage,是分页器的显示与否,比如:

javascript 复制代码
<el-pagination v-if="total > 0" ref="paginationRef">
</el-pagination>

至于我这里为什么叫totalPage,因为这个是经过二次封装的,没封装的就直接叫total。

同理 指令paginationRef.totalPage需要修改为paginationRef.total

3:有人问了paginationRef.total这个total是怎么来的,怎么命名的;

这个是官网的文档的组件,paginationRef这里就会获取你分页器的props。

比如:

这个total就指的elementUI的分页组件的props。一般因为是用来判断total数量是不是大于0显示;

大于0就显示了分页器,所以。。。懂了吧

4:又有人问了,为什么指令不直接写在el-table里。这个你可以自己去试试,会发现滚动不了。
至于原因:因为这个指令设置的是单独style的height高度,你审查元素就会发现el-table传参的height 他需要同步设置为他下级元素样式el-table__body-wrapper的高度,所以并不是设置style为height的高度这么简单。

5:代码的_.debounce是什么。这里是用的lodash的防抖函数,自己写一个防抖函数即可。

6:有的同学就要问了,那我直接封装一个方法或者其他方法或者mixins来计算行不行
都可以,你想怎么用怎么用,mixins的话比如:

javascript 复制代码
export default {
  data() {
    return {
      tableHeight: 0
    }
  },
  mounted() {
    this.calculateAndSetHeight()
  },
  methods: {
    calculateAndSetHeight() {
      if (this.$refs.tableRef) {
        const el = this.$refs.tableRef.$el
        const calculateHeight = () => {
          const windowHeight = window.innerHeight
          const topOffset = el.getBoundingClientRect().top
          const otherElementsHeight = 40
          let paginationHeight = 0
          const paginationRef = this.$refs.paginationRef
          if (paginationRef && paginationRef.totalPage) {
            paginationHeight = 55
          }
          this.tableHeight = `${
            windowHeight - topOffset - otherElementsHeight - paginationHeight
          }px`
        }
        const throttledCalculateHeight = _.debounce(calculateHeight, 500)
        throttledCalculateHeight()
        window.addEventListener('resize', throttledCalculateHeight)
        // 在组件销毁时移除事件监听器
        this.$once('hook:destroyed', () => {
          window.removeEventListener('resize', throttledCalculateHeight)
        })
      }
    }
  }
}

页面使用:

javascript 复制代码
<el-table ref="tableRef" :height="tableHeight">

这样就不用一个个标签像v-height div包起来了,但是ref和height就必要。

效果都是一样的,自己看着来。

ps:至于为什么要写这个功能,你能点进来看说明就是公司有一些犟货 觉得滚下去太麻烦了。或者是体验不是很好的,数据太多屏幕太小总要滚下去。

另外其实后台系统大部分用模板即可,有些模板自带有这种功能。

感谢你的阅读,如对你有帮助请收藏+关注!

只分享干货实战 和精品 ,从不啰嗦!!!

如某处不对请留言评论,欢迎指正~

博主可收徒、常玩QQ飞车,可一起来玩玩鸭~

相关推荐
拆房老料4 分钟前
【第四部分:Agentic 智能体设计模式】16. 一个 Prompt 搞不定复杂任务?试试 Prompt Chaining
java·前端·人工智能·设计模式·prompt
曹牧5 小时前
C#:空合并运算符
java·前端·数据库
小羊没烦恼!6 小时前
铁道部新客票系统设计(二)
开发语言·前端·数据库·python·oracle·c#·php
智能直播9 小时前
RK3518:1.5G 内存 + 8G 存储,如何跑起硬件编解码、Web、AI 识别、绿幕特效
前端·人工智能·5g
掘金酱10 小时前
【10.24 特别活动】AI 时代,程序员的新饭碗在哪里?
前端·人工智能·后端
excel10 小时前
多进程环境下使用 PM2 部署 Socket.IO:需要注意什么
前端
IT_陈寒10 小时前
Redis的原子性竟然失效了?记一次分布式锁翻车实录
前端·人工智能·后端
时间的情敌12 小时前
《回顾 2018 前端:Vue2 成熟期,Webpack4 发布,PWA 大火》
前端
Java后端的Ai之路12 小时前
前端技术Vue-09-webpack-vuejs-实战
前端·vue.js·webpack
LMT流氓兔12 小时前
第五单元——第4课:给工具参数加校验
java·前端·算法·ai·langchain