重写通用列表页的表格自适应高度功能

master
toesbieya 5 years ago
parent 5262127c59
commit 4a79a17402
  1. 91
      vue/full/src/view/_common/ListPage/autoAdaptHeightMixin.js
  2. 2
      vue/full/src/view/_common/ListPage/index.vue

@ -3,71 +3,84 @@
* 监听el-table动态设置max-height属性
*/
import {findComponentByTag} from "@/util/vue"
export default {
props: {
//容器距离视窗底部的理想距离,默认是页面margin+页脚高度
bottomDistance: {type: Number, default: 24 + 64}
},
data() {
return {
//el-table的max-height属性
tableMaxHeight: undefined,
//上一次的maxHeight,解决resize时表格高度不正确
lastTableMaxHeight: undefined,
//表格距离卡片容器底部的理想距离
expectedDistance: undefined
tableMaxHeight: undefined
}
},
methods: {
//设置表格距离卡片容器底部的理想距离(分页高度 + el-card的1px边距 + el-card padding)
calcExpectedDistance() {
const paginationHeight = this.$el.querySelector('.table-container > .el-pagination') ? 50 : 0
this.expectedDistance = paginationHeight + 1 + 20
//位于表格底部与容器底部之间元素的高度,目前只考虑分页
getExtraHeight() {
//el-card的1px边距 + el-card padding
const extra = 1 + 20
const pagination = this.$el.querySelector('.el-pagination')
return pagination ? extra + pagination.offsetHeight : extra
},
resize() {
//被keep-alive缓存后,由activated -> deactivated时,_inactive为true
//此时一般是路由向另一个页面切换,不进行后续操作
if (this._inactive === true) return
if (this.thisResizeIsTriggeredByLast()) {
return this.removeTriggerMark()
}
const clientHeight = window.innerHeight
//计算卡片容器底部距离视窗底部的距离
const containerRect = this.$el.getBoundingClientRect()
const containerDistance = clientHeight - containerRect.top - containerRect.height
const rect = this.$el.querySelector('.el-table').getBoundingClientRect()
//计算表格底部距离视窗底部的距离
const tableRect = this.$refs.table.$el.getBoundingClientRect()
const tableDistance = clientHeight - tableRect.top - tableRect.height
//表格顶部距离视窗底部的距离
const top = clientHeight - rect.top
if (this.expectedDistance === undefined) {
this.calcExpectedDistance()
}
//期望的表格底部距离视窗底部的距离
const expected = this.bottomDistance + this.getExtraHeight()
//期望的表格距离视窗底部的距离
const expectedTableDistance = containerDistance + this.expectedDistance
//超出期望的距离,必定是非负数
const overHeight = expectedTableDistance - tableDistance
//当前表格理论上的最大高度,不一定会应用
const newVal = top - expected
const oldVal = this.tableMaxHeight
//overHeight为0说明表格在卡片容器内
if (overHeight === 0) {
this.tableMaxHeight = this.lastTableMaxHeight
//表格最大高度并未超出期望
if (oldVal === undefined && newVal >= rect.height) {
return
}
else {
this.lastTableMaxHeight = this.tableMaxHeight
this.tableMaxHeight = tableRect.height - overHeight
if (oldVal !== newVal) {
this.willTriggeredNextResize()
this.tableMaxHeight = newVal
}
},
thisResizeIsTriggeredByLast() {
return this.$_hasResize === true
},
willTriggeredNextResize() {
this.$_hasResize = true
},
removeTriggerMark() {
this.$_hasResize = false
}
},
mounted() {
this.resizeObserver = new ResizeObserver(this.resize)
this.resizeObserver.observe(this.$el)
const searchFormInstance = findComponentByTag(this, 'search-form')
if (searchFormInstance) {
this.resizeObserver.observe(searchFormInstance.$el)
}
//为了用户体验,不使用防抖
this.$_resizeObserver = new ResizeObserver(this.resize)
this.$_resizeObserver.observe(this.$el)
//卸载resizeObserver
this.$once('hook:beforeDestroy', () => {
if (this.resizeObserver) {
this.resizeObserver.disconnect()
this.resizeObserver = null
if (this.$_resizeObserver) {
this.$_resizeObserver.disconnect()
this.$_resizeObserver = null
}
})
}

@ -61,7 +61,7 @@ export default {
table.scopedSlots.default = $scopedSlots.tableColumn
return (
<el-card v-loading={pageLoading} class="max-view-height">
<el-card v-loading={pageLoading}>
{this.renderSearchForm(search, $scopedSlots.searchForm)}
{this.renderButtons(buttons)}
{this.renderTableAndPagination({loading: dataLoading, table, pagination})}

Loading…
Cancel
Save