Element UI 组件库

自定义组件样式全面解析

这篇文章详细讲解了如何自定义 Element UI 组件样式,包括重写样式的技巧、注意事项以及常见组件的样式定制示例。

🎯 引言

学会这篇文章后,你将能够灵活地定制 Element UI 组件的样式,让你的前端界面更符合设计需求和用户体验。文章不仅涵盖重写样式的方法,还会详细介绍如何解决常见的样式穿透和作用域限制问题,并结合 Input、Button、Dialog 等常用组件实例,帮助你快速上手。


🎨 自定义组件样式

✨ 如何重写 Element UI 样式

Element UI 作为一套成熟的 Vue 2.0 UI 框架,提供了丰富的组件和默认样式,但很多时候我们需要根据业务需求,修改组件的样式。这里介绍几种常见的重写样式方法:

1. scoped 限制

Vue 组件中使用 <style scoped> 可以让样式只作用于当前组件的模板,防止样式污染其他组件。但这也会限制我们对 Element UI 组件内部深层元素的样式修改。

举个例子,如果你想修改一个 Element UI 组件内部的样式,直接在 scoped 样式里写选择器是不会生效的,因为样式被限制在当前组件的根元素范围内。

2. deep 深度选择

为了突破 scoped 限制,Vue 2.0 提供了 :deep 深度选择符,它们可以穿透样式作用域,直接修改子组件或第三方库内部的样式。

示例:

<template>
    <el-button>按钮</el-button>
</template>

<style scoped>
:deep(.el-button) {
    background-color: #409eff;
    color: white;
}
</style>

使用 :deep 可以让样式生效到 .el-button 这个 Element UI 组件的内部元素。

3. class 穿透技巧

除了深度选择器,另一个常用的做法是给组件外层添加自定义 class,然后利用更高权重的选择器来覆盖默认样式。

示例:

<template>
    <div class="custom-button">
        <el-button>按钮</el-button>
    </div>
</template>

<style scoped>
.custom-button >>> .el-button {
    border-radius: 20px;
}
</style>

这种方式更灵活,尤其是在复杂页面中,可以避免样式冲突。

4. 全局样式

如果需要修改大量或公共的 Element UI 样式,可以直接在项目的全局样式文件(比如 main.cssApp.vue 的无 scoped 样式里)进行覆盖。这样不会有 scoped 限制,但要注意选择器的优先级。

.el-button {
    font-weight: bold;
}
全局样式修改时,建议使用尽量具体的选择器,避免影响到无关组件。

⚠️ 重写样式注意事项

弹窗、抽屉等组件挂载在 body,为何样式改不动?

Element UI 的弹窗(el-dialog)、抽屉(el-drawer)等组件,默认通过 append-to-body 属性将组件挂载到 body 中,而不是当前组件的 DOM 树内。这带来两个影响:

  • 组件的 DOM 元素不在父组件作用域内,scoped 样式无法穿透到弹窗内部。
  • 使用 >>> :deep 等穿透符号也失效,因为样式作用于当前组件的 DOM 树,弹窗 DOM 在 body 外。

解决方案:

  • 使用全局样式文件修改弹窗样式。
  • 给弹窗组件添加自定义 class,再在全局样式中写对应样式。

示例:

<el-dialog title="示例弹窗" :visible.sync="dialogVisible" custom-class="custom-dialog">
    <p>弹窗内容</p>
</el-dialog>
.custom-dialog .el-dialog__header {
    background-color: #f56c6c;
    color: white;
}

🎯 重写常用组件样式案例

🔍 自定义 Input 样式(高度、边框、颜色)

Element UI 的 <el-input> 默认样式比较基础,我们可以通过深度选择或全局样式来定制高度、边框颜色等。

示例代码:

<template>
    <el-input placeholder="请输入内容" v-model="inputValue" />
</template>

<script>
export default {
    data() {
        return {
            inputValue: '',
        };
    },
};
</script>

<style lang="scss" scoped>
.el-input {
    :deep(.el-input__inner) {
        padding: 0 20px;
        color: red;
        border: 1px solid blue;
        background-color: transparent;
        border-radius: 0;
        height: 30px;
        line-height: 30px;
    }
}
</style>

🎨 自定义 Button 样式

按钮的悬浮和禁用状态是 UI 交互的重要体现,重写这部分样式可以让按钮更具品牌特色。

示例:

<template>
    <el-button>点击我</el-button>
</template>

<style lang="scss" scoped>
.el-button {
    width: 120px;
    height: 40px;
    padding: 0;
    background: #f0f9ff;
    border: 1px solid #c6e2ff;
    color: #409eff;
    font-size: 12px;
    border-radius: 6px;
}
</style>

🖼️ 自定义 Dialog 样式(边距、宽度)

Dialog 弹窗是常用的交互组件,调整宽度和边距能够更好地适配不同页面布局。

示例:

<template>
    <el-dialog title="自定义弹窗" :visible.sync="dialogVisible" custom-class="custom-dialog">
        <p>弹窗内容示例</p>
    </el-dialog>
</template>

<script>
export default {
    data() {
        return {
            dialogVisible: true,
        };
    },
};
</script>

<style lang="scss">
body {
    .custom-dialog {
        width: 600px;

        .el-dialog__header {
            background-color: #f5f7fa;
        }

        .el-dialog__body {
            padding: 20px;
        }
    }
}
</style>
全局修改样式,记得添加一个自定义类名 custom-dialog 避免全局污染。

🧾 小结

  • Element UI 样式被 scoped 限制时,使用 /deep/ 选择器可以穿透子组件样式。
  • 弹窗类组件因挂载在 body,需要通过全局样式和 custom-class 属性来自定义样式。
  • 自定义组件样式时,结合 class 穿透和全局样式,灵活调整元素高度、颜色和状态样式。

❓ 知识问答(Q&A)

Q:为什么直接在 scoped 样式里写 Element UI 组件选择器不生效?

A:因为 scoped 样式只作用于当前组件的 DOM 范围内,无法影响子组件的深层元素,需用 /deep/ 穿透或写全局样式。

Q:如何修改 Element UI 弹窗组件的宽度和边距?

A:给弹窗添加 custom-class,在全局样式中使用更高优先级选择器(通常需 !important)来覆盖默认样式。


🧪 小练习

练习 1

自定义 el-select 组件的下拉框样式,改变背景色和字体颜色。

<template>
    <el-select v-model="value" placeholder="请选择" class="custom-select">
        <el-option label="选项1" value="1" />
        <el-option label="选项2" value="2" />
    </el-select>
</template>

<script>
export default {
    data() {
        return {
            value: '',
        };
    },
};
</script>

<style lang="scss" scoped>
/* 在这里写你的样式 */
</style>

练习 2

自定义 el-checkbox 组件的勾选框颜色和大小。

<template>
    <el-checkbox v-model="checked" class="custom-checkbox">勾选我</el-checkbox>
</template>

<script>
export default {
    data() {
        return {
            checked: false,
        };
    },
};
</script>

<style lang="scss" scoped>
/* 在这里写你的样式 */
</style>

🎉 恭喜你已经掌握 Element UI 组件样式重写、样式穿透技巧及自定义常用组件样式的技能啦!