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

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_URLel-button>
          <el-button type="info" size="mini" plain v-copy="scope.row.httpUrl">HTTP_URLel-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%,如下所示:

Vue 修改 Element-UI 组件的原生样式_第1张图片

Vue 修改 Element-UI 组件的原生样式_第2张图片

但实际上,页面被渲染后并没有正常的显示,刚刚预设的 100% 宽度却被渲染覆盖成了100px。事有蹊跷,令人疑惑。
Vue 修改 Element-UI 组件的原生样式_第3张图片
于是,我突然想到,是不是没有给父组件设定宽度的原因导致的。于是我干脆直接给表格的宽度设定成一个固定值:400px,但结果还是一样——渲染后的页面表中,表格的每一列都被挤到了一起,还是 100px。

2、定位问题

网上很多文章也都记录了类似的问题,阅读其中几篇也很容易了解到其中的原理。这里我简单的总结猜测一下:Element-UI 的 el-tab 组件是利用 tab 的 “display:none” 来实现的,这就导致在属性为 “display:none” 的 tab 中,table 组件初始化时找不到规定的属性,于是只能给定一个默认的 100px 宽度值。

于是,网上有很多各种各样的解决方案:有说设置固定宽高的,有说设置延时(setTimeout)的,有说通过父元素的宽度预先给容器赋宽度的,还有的说通过 v-if 控制的等等等等。

但,问题不在这。

我们再来仔细地回看一下渲染后的 DOM 树:

Vue 修改 Element-UI 组件的原生样式_第4张图片

可以看到,我们引用 “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” 应该同时写,才能够作用成功。

保存刷新,问题解决!

你可能感兴趣的:(前端,vue.js,前端,elementui)