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

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

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

Loading…
Cancel
Save