Vue 修改 Element-UI 组件的原生样式

本文档记录了在使用Element-UI的el-tabs组件和el-table组件时遇到的样式问题。当el-table在el-tab-panel内且未立即渲染时,表格宽度显示为100px,而非预期的100%。经过分析,发现是由于el-tab的display:none特性导致表格初始化宽度异常。通过使用/deep/选择器和!important强制设定表格宽度为100%,成功解决了样式覆盖问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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” 应该同时写,才能够作用成功。

保存刷新,问题解决!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值