# 利用继承修改vue组件，解决el-table中max-height为比例值的滚动问

{% embed url="<https://v.douyin.com/rjCs5AS/>" %}

{% embed url="<https://www.bilibili.com/video/BV1BS4y1m7MR/>" %}

大家有没有发现

el-table 的 max-height 不能设百分比

包括 vh 他的一定情况下都有问题

我们来看一下哈我们拿 vh 先来举例子

现在这个高度就是50 vh

这高度没问题

但是呢

他下边还有数据我们看不到了

因为他没法滚动了

但同样是50vh

我们换成

height

大家看这就可以滚动了

所以呢很奇怪

我们先来看一下

他现在滚动的这个是哪一个 div

我们来看一下这个

这个的高度现在是

然后呢他内层的高度是1,

我们先来看一下他的

scroll-top

大家看 551 我稍微滚动一点

再看

说明我们现在滚动的就是这个层

这个层自身只有160像素

但是它里边的内容比较高

1,420像素

所以他就有滚动的效果

但是如果我们把它改成 max-height

大家看这个层就不是160了

他就跟里边一样高了

所以他就不能滚动了

那我们把它再加一个高度哈

哎！ px

大家看，这样就可以滚动了

那为什么我们用 max-height 的时候

他就没有高度呢

这个我们一会再说

我们先来分析一下他为什么会要

有这个 div

我之前可能也说过哈

就是el-table

他为了实现这种表头的固定他会在

组件里边会画几个 div

一个是表头放在这

然后呢还有一个就是

表格的主体内容

然后我们滚动的时候呢

他是在主体内容里边

去做这个上下的滚动

这样来实现这个表头的浮动的效果

我们设的那个max-height是针对谁呢

是针对整个这个表表格的

全部的高度也就是说

他组件内部还要计算表头有多高

然后下边减掉表头

让他填充剩余的空间

所以呢

就导致他需要把下边设置一个高度

那他为什么就没设置上呢

我们先来翻一下代码

我们搜一下这个啊

搜的时候可能第一次搜他找不到

我们把这个排除文件打开

这样他可以搜到 node\_modules 里的文件

然后呢我们找到这个

table.vue

大家看，就这个层

这个层他有一个 style

然后bodyHeight

我们看一下bodyHeight

这是一个计算方法

然后 bodyHeight() 怎么写的呢

大家看，首先呢解构了几个对象（1个对象的几个属性）

我们先不管他这个不重要

然后他这判断用户是设置了 height

还是设置了 max height

如果设置了 height 呢

他就直接设置一个 height 的样式

大概这个 body height 肯定就是刚才那个

然后如果用户设置的是 max height

这时候他怎么处理的呢

他会把用户设置个 max height 做一个

格式化嗯

这个 pass height 怎么写呢看一下

大家看

height 是不是 number

如果是 number 呢他直接返回

如果不是的话呢

他会判断是不是以 px 结尾

大家看如果不是 px 结尾的话呢

他就原封不动返回了就是你写的50vh

他就返回了一个50vh

好我们继续看

我们这个地方拿到的就是50vh

然后他又判断50vh是不是number（类型）

那肯定不是

不是的话呢整个这个 if 都不走了

最终什么样式也没有

所以他就没有设置这个大小

包括百分比他都不会再设置了

那既然不设置

他就不会出现滚动条对吧

好那想到这呢我们可能

很多同学跟我一样

第一想法就是那既然它不支持

我们自己在这计算吧

我们最终返回一个这样的呗

clc 然后呢比如说50位置

减去他要计算的那些高度

就是他在这不是做了减减法吗

我把这些高度都拿过来计算一遍

在这减这种方法

在 vh 的情况下没有任何问题

效果特别好

但是放成了百分比就有问题了

那具体的原因哈

由于时间关系

我打算把它单出一期视频

我们先不管他为什么

就知道用百分比的情况下

这种方法是不可行的

所以呢我们要考虑其他的方法

什么方法呢

我们来看这个demo

这是一个特别简单的外层

然后里层两个容器我模拟了一下

现在呢就是这个样子

看看表头表数据

我们现在要用

flex 布局来实现这种效果的话

就特别简单

因为表头固定

然后让下边自动填充

剩余的空间就可以了

对吧

而且他有一个好处就是即使

el-table 组件给他

下边的表数据设置了一个高度

我可以让他不生效

我们来看一下

现在是flex布局

然后呢

方向是纵向的

好接下来呢

我把这个

加一个flex-grow

对吧？让他自动填充剩余的空间

大家看一下他就自动填充了

但是呢我们要注意

我们要想着把表头

flex-shrink改成

因为他默认是

他会自动缩小弗莱克斯是硬克等于

好这样就没有问题了

大家看而且好就好在刚才我说的

el-table给设的这个高度已经失效了

他完全遵循这个flex-grow了

好

那我们回过头来再来改刚才这个demo

我们想办法先把外边 table

改成 flex 布局

display 等于 flex

好现在布局乱了

因为他默认是横向布局的

我们把 flex direction 改成 column

改成 column 以后大家注意看

上面的表头没了

为什么呢就是因为它 shrink

它自动缩小了

我们把 flex

shrink改成

大家看！表头出来了

然后呢我们再把它下边 body-wapper

把这个

flax-grow:1 挑出来

好这样的话呢就可以了

但是哈还没完

我们先把这个样式先写出来（在项目里）

回到这个项目

我们写个 style

然后呢这里边我们

.el-table

display 等于 flex

好我们先来看一下

我们先把 column 去掉看它乱不乱

大家看乱了（说明样式生效了）

我们再把column加上

说明现在是column布局了

而且他现在表头没了

注意看

所以呢我们要把表头加上

.el-table

然后呢 flex-shrink:

刷新

嗯

啊！这块得用穿透

好大家看有了

（关于这个穿透的东西...

... 我之前有一个视频的合集 ...

...大家不懂可以去看哈） ok

我们再往下

再把那个

grow加上， body-wrapper 哎这有了

把这个 flex:1 加上

其实 flex:

就相当于把shrink和grow一起设置了

我们单独设置吧

这个都行其实 ok

看上去可以了哈

但有一种情况他会出问题

就是如果这个表格出现固定列

比如说我现在把它弄窄一点儿

三百像素

然后呢我让第一列出现固定的效果 fixed

大家看在滚动的时候

他前面这一列就不滚动了

所以呢这是我们要解决的第二个问题

怎么解决呢

我们先来看一下原因

跟那个刚才的类似

他这有一个 fix-body-wrapper

他这个层现在是没有（设置）高度的 （导致里外一样高）

其实我们要把这个层设置高度

也是可以滚动了

比如说我们给他设一个

随便设一个（先）

大家看他就可以滚动了

所以呢我们要找到（源码）里找到这个

注意看这他有一个 fixedBodyHeight 这个样式在 style 里

我们看一下这个

那关于这个 height

跟刚才的写法其实我们刚才看过了

算法其实类似

我们现在需要在这加一个 else

就是他不是 number 的时候呢

要else if

判断他是不是 vh 或者百分比哈

所以这块

我们直接在这改肯定是不行的

他不走

那怎么办呢我们只能自己

搞一个组件来继承这个

把它覆盖掉！好

我们新建一个组件

components 新建一个 el-table2.vue

然后这里边呢就 script

然后 ...

这里比较简单啊我们exttends继承

继承是什么呢

import 呢把刚才那个

table 导进来

然后呢这块

table导进来

继承的退保

这样这个组件就完事了啊

一会我们再写覆盖的方法

我先把这个组件导到main.js里边

先把它导进来

嗯我先复制一下刚才那个组件的地址

好然后呢我们起个名叫 ELTable

然后呢

然后我们在项目里再用的时候

就把这改一下

就用2 我们先来看一下可不可以

好没问题

没问题以后呢

说明他现在用的是我们这个2了

然后

我们再把他的刚才这个方法拿过来

fixedBodyHeight

他是在一个计算属性里

所以呢 computed

这个方法

这个方法我们没有

我们还得把这个导一下

parseHeight

在这

在这个util里边

那我们也把它导一下

嗯（element）我把这个复制一下地址吧

util

copy相对路径

粘过来

从element-ui开始

好

然后这样的话呢我们也有这个方法了

这回呢我们在这

console.log一下

看看走不走

大家看走了对吧

那接下来呢就是我们要把这个改造了

那就简单了

我们

在这加个判断

else if 然后呢 maxHeight

判断一下 match

\d 是不是数字加

vh呗

vh 或者 %

如果是的话走这里

那这里边怎么处理呢

我们按照他这个算法算一下

我们怎么写呢

这个高度很容易计算

注意看因为他现在是一个

position 等于 absolute

大家看！absolute

所以呢他会找到外层的

非 static 元素的

容器作为锚定 大家看

就这个容器

那这个容器现在有多高呢

这个容器

就是

整个这个el-table的高度

也就是说对于他下边这一小块

就这一小块的话

如果你写百分之百

就是整个table的高度

然后你去减剩余的高度就可以了

所以呢

这块我们其实是用不到maxHeight了

我们把它改成百分之百就行

声明个变量 let

比如说 resHeight

等于

什么呢等于他判断了一下大家看

我把这判断先拿过来

其实我们就把maxHeight

改成百分之百就行

把这一块改成

百分之百

同理呢

啊百分之百减去他

那那这块应该是这样写

（这个删掉）

嗯

百分之百

减去

这个我们把它拼成一个字母串

这样写

然后否则的话呢就是百分之百

然后再往下

他判断这个我们也是把它拿过来

还是 resHeight

减等于… 他也是要减去嘛 对吧！我们还是

我让他等于

他这样

他自身继续减去这个

啊对了要加 px

这个要加 px

ok 这实现了刚才那个减等于的效果

再往后这个一样

他没有判断直接减等于

那我们也是等于

减去这个

出来就这 px

最后呢我们把它

返回这块就

单位了

maxHeight注意

我们要给他拼接上什么

calc

好我们来试一下啊刷新

然后呢我们滚动一点

找到这个类往上

不对 50vh

啊错了

这块应该用这个错了 sorry

我们再刷新一下

稍微滚动一点看一下

这个就对了

100减去0减48减0啊这些无所谓

反正他效果是可以的打开

ok 那这样的话呢

我们以后也可以把这个样式拿进来

就我们刚才写的这个样式

大家看

没有问题

ok 以后的话我们再使用

（max-height是比例值的）el-table就可以加一个

大家看！把它去掉

滚动不了了

有问题了

这样左右能滚动但上下滚动不了了

但是呢如果我们加一个

相当于我们

把一些东西给重新覆盖重写了

这样的话就可以了
