问题产生原因
-
借助Element官方文档,了解到
max-height属性 合法值为 数字或单位为 px的高度(详见下图);因而,当赋值为calc(100vh - 100px)等时,并不符合官方要求 -
分别使用合法值和calc计算值为
max-height赋值,比较二者于样式上有何差异后者较前者,于
el-table__body-wrapper、el-table__fixed-body-wrapper两个DOM元素中,均缺失了max-height属性,进而最终导致滚动条无法显现(下图仅针对el-table__body-wrapper做对比展示) -
具体缺失原因,只能查阅源代码才能明晰
依照路径node_modules/element-ui/table/src/table.vue,进入对应组件文件
通过按键组合Ctrl+F,调出编辑器搜索框,分别搜索上文提到的两个DOM元素
分析得知,二者分别绑定了
bodyHeight、fixedBodyHeight两大对象
通过进一步搜索,可知悉二者均为计算属性bodyHeight() { const { headerHeight = 0, bodyHeight, footerHeight = 0} = this.layout; if (this.height) { return { height: bodyHeight ? bodyHeight + 'px' : '' }; } else if (this.maxHeight) { const maxHeight = parseHeight(this.maxHeight); if (typeof maxHeight === 'number') { return { 'max-height': (maxHeight - footerHeight - (this.showHeader ? headerHeight : 0)) + 'px' }; } } return {}; }, fixedBodyHeight() { if (this.height) { return { height: this.layout.fixedBodyHeight ? this.layout.fixedBodyHeight + 'px' : '' }; } else if (this.maxHeight) { let maxHeight = parseHeight(this.maxHeight); if (typeof maxHeight === 'number') { maxHeight = this.layout.scrollX ? maxHeight - this.layout.gutterWidth : maxHeight; if (this.showHeader) { maxHeight -= this.layout.headerHeight; } maxHeight -= this.layout.footerHeight; return { 'max-height': maxHeight + 'px' }; } } return {}; },上方代码中定义的
max-height属性,会经过parseHeight方法 处理后返回export function parseHeight(height) { if (typeof height === 'number') { return height; } if (typeof height === 'string') { if (/^\d+(?:px)?$/.test(height)) { return parseInt(height, 10); } else { return height; } } return null; }当
parseHeight方法参数值为calc(100vh - 100px)等时,会原封不动地返回。该返回值在bodyHeight、fixedBodyHeight计算属性内部,均无法通过typeof maxHeight === 'number'判断;最终导致返回{}
处理方法
-
借助组件继承,可以方便以任意组件为基础,做调整或进一步开发
-
依赖此API,可以在
el-table组件 的基础上,对bodyHeight、fixedBodyHeight内部逻辑进行调整/* el-change.js */ // 引入待继承的组件 import { Table } from 'element-ui' // 引入所涉及的外部工具方法 import { parseHeight } from 'element-ui/packages/table/src/util' const TablePatch = { // 继承组件 extends: Table, computed: { bodyHeight() { xxxx; if (xxx) { xxx; } else if (xxx) { xxx; if (xxx) { xxx; } // 针对calc定义的高度,增补计算逻辑(增补内容,以上方为参照) if (typeof maxHeight === "string") { if (maxHeight.startsWith("calc")) { return { "max-height": `calc(${maxHeight} - ${footerHeight}px - ${this.showHeader ? headerHeight : 0}px)`, }; } } } xxx; }, fixedBodyHeight() { if (xxx) { xxx; } else if (xxx) { xxx; if (xxx) { xxx; } // 针对calc定义的高度,增补计算逻辑(增补内容,以上方为参照) if (typeof maxHeight === "string") { if (maxHeight.startsWith("calc")) { const { gutterWidth, headerHeight, footerHeight } = this.layout; maxHeight = this.layout.scrollX ? `calc(${maxHeight} - ${gutterWidth}px)` : maxHeight; this.showHeader && (maxHeight = `calc(${maxHeight} - ${headerHeight}px)`); maxHeight = `calc(${maxHeight} - ${footerHeight}px)`; return { "max-height": maxHeight }; } } } xxx; }, }, }; export default { install(Vue) { // 全局注册组件(使用源组件名称) Vue.component(Table.name, TablePatch); }, };/* main.js */ xxx // 引入自定义插件 import elChange from '@/plugins/el-change' // 使用插件 Vue.use(elChange) xxx