1、问题描述
前端使用 Element-UI 组件库,常常会遇到样式不匹配或样式显示异常的情况,但之前每每遇到这种问题,总是想着换一个组件试试,对于原来组件的样式问题就常常不了了之。
最近,我在使用 el-tabs 组件嵌套 el-table 时,又遇到了这种问题,具体表现为:我在子标签页(el-tab)中插入表格(eltable)后,页面表格的宽度显示异常。具体代码如下:
<el-tabs v-model="activeTabName">
<el-tab-pane lazy label="代码仓库" name="Gitcode">
<el-table
v-if="activeName === 'List' && activeTabName === 'Gitcode'"
:data="gitcodeRepos"
stripe
class="repo_list">
<el-table-column
prop="gitProjectId"
label="Repo ID"
width="10%">
</el-table-column>
<el-table-column
prop="name"
label="仓库名称"
width="10%">
<template v-slot="scope">
<a :href="scope.row.webUrl" target="_blank" style="text-decoration: none;">{{scope.row.name}}</a>
</template>
</el-table-column>
<el-table-column
prop="description"
label="仓库描述"
width="15%">
</el-table-column>
<el-table-column
prop="forkEnabled"
label="Fork"
width="5%">
<template v-slot="scope">
<el-tag v-if="scope.row.forkEnabled" type="success" effect="dark">开启</el-tag>
<el-tag v-else type="info" effect="dark">关闭</el-tag>
</template>
</el-table-column>
<el-table-column
prop="visibilityLevel"
label="可见级别"
width="5%">
<template v-slot="scope">
<el-tag v-if="scope.row.visibilityLevel === 0" type="danger">私有</el-tag>
<el-tag v-else-if="scope.row.visibilityLevel === 20" type="warning">内部</el-tag>
<el-tag v-else>公共</el-tag>
</template>
</el-table-column>
<el-table-column
prop="webUrl"
label="仓库地址"
width="25%">
</el-table-column>
<el-table-column
prop=""
label="操作"
width="30%">
<template v-slot="scope">
<el-button type="primary" size="mini" plain @click="handleEditGitCodeRepo()">编辑</el-button>
<el-popconfirm
style="margin-left:10px; margin-right:10px;"
confirm-button-text='确认'
cancel-button-text='取消'
icon="el-icon-info"
icon-color="red"
title="确定删除吗?"
@confirm="handleRemoveGitCodeRepo(scope.row.gitProjectId)"
>
<el-button slot="reference" type="danger" size="mini" plain>删除</el-button>
</el-popconfirm>
<el-button type="info" size="mini" plain v-copy="scope.row.sshUrl">SSH_URL</el-button>
<el-button type="info" size="mini" plain v-copy="scope.row.httpUrl">HTTP_URL</el-button>
<el-button type="warning" size="mini" plain><a :href="scope.row.webUrl" target="_blank" style="text-decoration: none">进入仓库</a></el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<style scoped lang="less">
.repo_list{
width: 100%;
}
</style>
可以看到,这个表格并非在页面初始化的挂载阶段进行挂载,而是通过 v-if 进行显式控制,即“activeName”和“activeTabName”两个变量均满足时,才能够被渲染和挂载。至于表格本身的样式,我在表格样式中设置了宽度为 100%,如下所示:
但实际上,页面被渲染后并没有正常的显示,刚刚预设的 100% 宽度却被渲染覆盖成了100px。事有蹊跷,令人疑惑。
于是,我突然想到,是不是没有给父组件设定宽度的原因导致的。于是我干脆直接给表格的宽度设定成一个固定值:400px,但结果还是一样——渲染后的页面表中,表格的每一列都被挤到了一起,还是 100px。
2、定位问题
网上很多文章也都记录了类似的问题,阅读其中几篇也很容易了解到其中的原理。这里我简单的总结猜测一下:Element-UI 的 el-tab 组件是利用 tab 的 “display:none” 来实现的,这就导致在属性为 “display:none” 的 tab 中,table 组件初始化时找不到规定的属性,于是只能给定一个默认的 100px 宽度值。
于是,网上有很多各种各样的解决方案:有说设置固定宽高的,有说设置延时(setTimeout)的,有说通过父元素的宽度预先给容器赋宽度的,还有的说通过 v-if 控制的等等等等。
但,问题不在这。
我们再来仔细地回看一下渲染后的 DOM 树:
可以看到,我们引用 “repo_list” 类的这个节点样式已经被更改了,但是其子节点 “table” 仍然没受其影响。因此,我们可以尝试修改 el-table 下的 table 子组件的样式,看看问题能否解决。
3、解决问题
如何修改 Element-UI 的原生组件样式?这个问题其实很简单——使用CSS的 less 预处理语言即可。
对于上述代码的 CSS 样式表,可以做出如下的更改:
<style scoped lang="less">
.repo_list{
width: 100%;
/deep/ table {
width: 100% !important;
}
}
</style>
此处应该注意,“/deep/” 和 “!important” 应该同时写,才能够作用成功。
保存刷新,问题解决!