【ElementUI】通过改变SCSS变量修改ElementUI样式

本文介绍如何通过修改SCSS变量来自定义ElementUI样式,包括创建样式文件、引入文件、覆盖样式变量及修改特定样式的方法。

目录

一、创建覆盖ElementUI样式的文件

二、在项目入口文件中引入上记文件

三、覆盖ElementUI的样式变量

四、如何修改变量以外的样式

五、既然可以直接修改样式,为什么还要覆盖变量


 

大家好

 

在Element官网中,提供了四种方法来对样式进行自定义:

  1. 主题编辑器
  2. 仅替换主题色
  3. 在项目中改变SCSS变量
  4. 命令行主题工具

 

本文将按照官网的描述,介绍如何在使用了SCSS的项目中,通过改变SCSS变量修改ElementUI样式,并在此基础上给出示例和补充。

 

一、创建覆盖ElementUI样式的文件

Element 的 theme-chalk 使用 SCSS 编写,我们可以直接在项目中改变 Element 的样式变量。

首先,我们新建一个样式文件,例如 element-variables.scss,用来覆盖ElementUI的样式。(在本文示例中,该文件创建在src根目录)

 

以下是该文件的基本代码:

// element-variables.scss

/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';

@import "~element-ui/packages/theme-chalk/src/index";

上记代码中,我们还没有添加我们想要覆盖的样式。

其中的$--font-path是字体路径变量,是必须进行覆盖的,将其赋值为 Element 中 icon 图标所在的相对路径即可。

"~element-ui/packages/theme-chalk/src/index"是ElementUI的SCSS文件,文件的内容是引用各个组件的SCSS文件。所以如果我们是按需引入组件,此处也可以只引入对应组件的SCSS文件。

关于“~”的用法:URL中“~”后的内容会作为一个模块请求被解析,可以参考VUE-CLI的文档 https://cli.vuejs.org/zh/guide/html-and-static-assets.html#url-%E8%BD%AC%E6%8D%A2%E8%A7%84%E5%88%99

 

二、在项目入口文件中引入上记文件

然后,为了在项目中应用上记文件,我们需要在入口文件中引用,代码如下:

// main.js

import Vue from 'vue'
import Element from 'element-ui'
import './element-variables.scss'

Vue.use(Element)

到此为止,我们在样式文件的修改就可以反映在项目中啦。

 

三、覆盖ElementUI的样式变量

ElementUI预置了一些样式变量,我们可以查看想要修改的组件的样式文件,也可以通过Element的在线工具(https://element.eleme.io/#/zh-CN/theme/preview)了解可以修改哪些变量。

最后,我们来覆盖ElementUI的样式变量。以修改按钮的样式为例:

ElementUI的按钮提供了多种大小,如果在项目中经常使用某一种大小的按钮,我们一般会在Vue安装Element时进行设定。比如我们使用超小按钮:

// main.js

import Vue from 'vue'
import Element from 'element-ui'
import './element-variables.scss'

Vue.use(ElementUI, {size: 'mini'})

我们来看看这个超小按钮的样子吧:

<!-- index.vue -->
<template>
  <div>
    <el-button>ボタン</el-button>
  </div>
</template>

 

可有时候,我们觉得超小型按钮也有点太大了,我们想调整按钮的大小。于是我们可以覆盖下记两个变量:

// element-variables.scss

/* 改变 超小按钮 的大小 */
$--button-mini-padding-vertical: 3px; // 纵向内边距 原始为7px
$--button-mini-padding-horizontal: 7px; // 横向内边距 原始为15px

/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';

@import "~element-ui/packages/theme-chalk/src/index";

现在我们再来看这个按钮,是不是比原来还要小啦

 

四、如何修改变量以外的样式

有的时候,只通过修改变量,并不能完全满足我们的需求。一些组件的样式,并未使用SCSS变量。遇到这种情况,我们可以选择覆盖Element的Class。

以下是一个单独修改卡片标题高度的例子:

<!-- index.vue -->
<template>
  <div>
    <el-card header="カード">内容</el-card>
  </div>
</template>

我们来修改影响标题高度的样式:

// element-variables.scss


/* 改变 超小按钮 的大小 */
$--button-mini-padding-vertical: 3px; // 纵向内边距 原始为7px
$--button-mini-padding-horizontal: 7px; // 横向内边距 原始为15px

/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';

@import "~element-ui/packages/theme-chalk/src/index";

// 修改卡片样式
.el-card {
  .el-card__header {
    padding: 6px 18px; // 卡片标题内边距 原始为18px 20px;
  }
}

这样就大功告成啦~

 

五、既然可以直接修改样式,为什么还要覆盖变量

像主题色之类的样式,组件之间是共用的。只改变一个组件中的主题色样式,会与其他组件的颜色主题不一致,产生违和感。

这其实就是变量的优点,可复用。而且变量名包含语义,读起来也更容易理解,方便维护。

 

 

以上就是本文的全部内容啦,本人能力有限,如果记述有误,还请您留言指出,感谢谅解和支持,欢迎留言评论!

<think>我们参考了用户提供的引用内容,其中引用[1]展示了内联样式中将px转换为vw的方法(虽然被注释掉了rem转换,但思路类似)。用户的需求是覆盖ElementUI样式变量并将单位px替换为rem。 思路: 1. ElementUI使用SCSS变量来定义样式,因此我们可以通过修改这些变量改变样式。 2. 用户想要将样式变量中的px单位转换为rem,这通常是为了实现响应式布局(rem相对于根元素字体大小变化)。 3. 我们需要覆盖ElementUISCSS变量,将其中以px为单位的数值转换为rem。 步骤: a. 安装必要的依赖:sass-loader、node-sass(或dart-sass,注意兼容性)。 b. 在项目中创建一个scss文件(例如element-variables.scss),用于覆盖ElementUI变量。 c. 在这个文件中,首先定义一个函数用于将px转换为rem。假设设计稿以16px为基准(即1rem=16px),则转换函数可以这样写: ```scss $base-font-size: 16px; // 根据实际情况调整,通常与html元素的font-size一致 @function px2rem($px) { @return ($px / $base-font-size) * 1rem; } ``` d. 然后,我们需要覆盖ElementUI变量ElementUI变量通常以$--开头,例如`$--color-primary`。但是要注意,很多尺寸变量是带px单位的,我们需要将这些px单位转换为rem。 例如,覆盖按钮的字体大小变量: ```scss $--font-size-base: px2rem(14px); // 将基础字体大小设置为14px转换后的rem值 ``` 但是,ElementUI变量很多,我们不可能一个个手动转换。因此,我们可以考虑在变量赋值的地方使用我们的转换函数。 e. 但是注意:ElementUI变量文件中,有些变量可能是由其他变量计算得到的,而且有些变量可能被多个地方使用。因此,我们需要在引入ElementUISCSS变量文件之前,先定义我们的转换函数,然后覆盖那些需要转换的变量。 实际上,我们可以在element-variables.scss中这样写: ```scss /* 改变主题变量,并引入转换函数 */ $base-font-size: 16px; @function px2rem($px) { @return ($px / $base-font-size) * 1rem; } // 覆盖ElementUI变量,将尺寸相关的变量都转换成rem // 注意:我们需要覆盖的变量列表可以参考ElementUIscss变量文件(在node_modules/element-ui/packages/theme-chalk/src/common/var.scss) $--font-size-base: px2rem(14px); $--font-size-small: px2rem(12px); $--font-size-large: px2rem(18px); // ... 根据需要覆盖更多变量 // 然后引入ElementUI样式文件 @import "~element-ui/packages/theme-chalk/src/index"; ``` f. 然而,上述方法需要手动覆盖每一个尺寸变量,工作量较大。另一种思路是:在ElementUI编译样式之前,将其变量中的所有px单位转换为rem。我们可以利用SCSS的custom function来实现全局替换,但这种方法比较复杂。 更常见的做法是:在项目中使用postcss的插件(如postcss-pxtorem)来将整个项目中的px单位转换为rem,包括ElementUI样式。这样就不需要单独覆盖ElementUI变量了。 g. 如果用户坚持要只修改ElementUI变量,那么就需要逐个修改尺寸变量(使用px2rem函数转换)。但注意,ElementUI变量非常多,而且有些变量可能是复合值(包含多个值,比如padding: 10px 20px;),这种变量不能直接转换,需要拆开。 考虑到实际可行性,推荐使用postcss-pxtorem方案。但如果用户确实需要在SCSS变量层面转换,则只能手动覆盖。 根据引用[2]中提到的循环生成栅格化布局,我们可以借鉴循环来覆盖多个变量?但是ElementUI变量是分散的,不能循环覆盖。 因此,我们提供两种方案: 方案一:使用postcss-pxtorem插件(推荐) 步骤: 1. 安装postcss-pxtorem: ``` npm install postcss-pxtorem -D ``` 2. 在项目根目录创建postcss.config.js,配置如下: ```javascript module.exports = { plugins: { &#39;postcss-pxtorem&#39;: { rootValue: 16, // 基准值,1rem=16px propList: [&#39;*&#39;], // 对所有属性进行转换 // 注意:ElementUI样式也需要转换,所以需要包含node_modules内的element-ui selectorBlackList: [&#39;.el-&#39;], // 避免转换.el-开头的类,因为ElementUI的类都是以el-开头,所以这里要排除,否则会转换两次?但是实际上我们就是要转换ElementUI样式,所以不能排除。 // 但是,如果我们的代码中也有px单位,并且我们希望转换,那么就不排除。然而,我们可能希望只转换ElementUI的?所以可能需要另外配置。 // 实际上,这个插件会转换所有样式文件中的px单位(包括node_modules中的)。所以,我们可以通过配置include来指定只转换element-ui的样式文件,或者配置exclude来排除其他文件。 // 或者,我们不做排除,整个项目都转换。那么我们在自己的代码中也可以使用px,然后被转换成rem。 } } } ``` 但是,注意:如果项目中有不需要转换的地方,可以通过selectorBlackList或者不写propList来排除。 方案二:手动覆盖SCSS变量(适用于需要定制主题,且转换变量不多的情况) 步骤: 1. 在项目中创建element-variables.scss文件,内容如前面所述。 2. 在项目的入口文件(如main.js)中引入这个scss文件,而不是直接引入ElementUIcss文件。 3. 确保项目配置了scss-loader。 由于用户明确要求覆盖ElementUI样式变量,所以这里我们重点讲解方案二的具体实现。 具体步骤(方案二): 1. 安装sass-loader和node-sass(注意版本兼容性): ``` npm install sass-loader node-sass -D ``` 2. 创建element-variables.scss文件,例如在src/styles目录下。 3.element-variables.scss中编写覆盖代码: ```scss // 定义转换函数 $base-font-size: 16px; // 基准字体大小,根据实际情况调整 @function px2rem($px) { @return ($px / $base-font-size) * 1rem; } // 覆盖ElementUI的尺寸变量(部分示例,根据实际需要覆盖) $--font-size-base: px2rem(14px); // 基础字体大小 $--font-size-small: px2rem(12px); $--font-size-large: px2rem(18px); // 按钮相关 $--button-font-size: px2rem(14px); $--button-border-radius: px2rem(4px); $--button-padding-vertical: px2rem(10px); $--button-padding-horizontal: px2rem(20px); // 输入框 $--input-height: px2rem(40px); // ... 其他变量,请参考node_modules/element-ui/packages/theme-chalk/src/common/var.scss // 引入ElementUI样式文件 @import "~element-ui/packages/theme-chalk/src/index"; ``` 4. 在main.js中引入这个scss文件: ```javascript import Vue from &#39;vue&#39; import ElementUI from &#39;element-ui&#39; import &#39;./styles/element-variables.scss&#39; // 注意路径 Vue.use(ElementUI) ``` 5. 修改vue.config.js配置文件(如果没有则创建),确保scss文件能够被正确编译。通常不需要额外配置,但如果有问题,可以检查sass-loader的配置。 注意:这种方法需要覆盖所有尺寸变量,否则没有覆盖的变量仍会使用px单位。因此,工作量较大,且需要了解ElementUI变量名。 结论:推荐使用方案一(postcss-pxtorem)进行全局转换,包括ElementUI和自定义样式的px单位。如果用户需要结合主题定制(如修改颜色等)且只转换部分变量,则采用方案二。 根据用户提供的引用[4]中提到了Vue组件和样式作用域,这里需要注意:在方案二中,我们通过覆盖全局样式变量来实现,所以不会受到scoped的影响。而方案一通过postcss插件转换,也是全局生效的。 因此,请用户根据实际需求选择方案。 §§相关问题§§ 1. 如何配置postcss-pxtorem来只转换ElementUI样式? 2. 在手动覆盖ElementUISCSS变量时,如何找到需要覆盖的变量名? 3. 如何确保转换后的ElementUI样式在移动端自适应? 4.Vue项目中,如何处理全局样式和组件局部样式中的单位转换? </think>以下是针对覆盖 ElementUI 样式变量并将 px 单位转换为 rem 的完整解决方案,结合 Vue 项目实现: ### 解决方案 通过创建 SCSS 全局样式文件 + 自定义转换函数实现 #### 步骤 1:创建 SCSS 变量覆盖文件 在项目中创建 `src/styles/element-variables.scss` 文件: ```scss // 定义基础字体大小(1rem = 16px) $base-rem-size: 16px !default; // px 转 rem 函数(参考引用[1]思路) @function px2rem($px) { @return ($px / $base-rem-size) * 1rem; } // 覆盖 ElementUI 尺寸变量(按需添加更多变量) $--font-size-base: px2rem(14px); $--font-size-small: px2rem(12px); $--font-size-large: px2rem(18px); $--button-padding-vertical: px2rem(10px); $--button-padding-horizontal: px2rem(20px); $--input-height: px2rem(40px); // 引入 ElementUI 源文件(路径根据实际安装位置调整) @import "~element-ui/packages/theme-chalk/src/index"; ``` #### 步骤 2:修改 Vue 项目配置 在 `vue.config.js` 中添加 SCSS 全局注入(不存在则创建文件): ```js module.exports = { css: { loaderOptions: { sass: { prependData: `@import "@/styles/element-variables.scss";` } } } } ``` #### 步骤 3:动态设置根字体大小 在 `src/main.js` 中添加响应式基准值: ```js // 设置根元素字体大小(基于 1920px 设计稿) function setRootFontSize() { const baseSize = 16; const scale = document.documentElement.clientWidth / 1920; document.documentElement.style.fontSize = baseSize * scale + &#39;px&#39;; } window.addEventListener(&#39;resize&#39;, setRootFontSize); setRootFontSize(); ``` #### 步骤 4:移除原有 ElementUI 样式引入 在原 ElementUI 引入位置改为: ```js // 删除原有样式引入 // import &#39;element-ui/lib/theme-chalk/index.css&#39; ``` ### 关键实现原理 1. **SCSS 函数覆盖**(参考引用[1]) - 创建 `px2rem()` 转换函数处理所有尺寸变量 -ElementUI 加载前覆盖其全局 SCSS 变量 2. **响应式适配** - 通过 JS 动态计算根字体大小 - 使用 `rem` 单位实现布局自适应 3. **构建注入** - 通过 `sass-loader` 全局注入变量文件 - 确保所有组件使用转换后的变量值 ### 注意事项 1. **变量覆盖范围**: - 需覆盖所有包含 `px` 单位的变量,完整变量列表参考: `node_modules/element-ui/packages/theme-chalk/src/common/var.scss` 2. **复合值处理**: 对于类似 `$--border-radius-base: 2px 2px 2px 2px;` 的多值变量: ```scss $--border-radius-base: px2rem(2px) px2rem(2px) px2rem(2px) px2rem(2px); ``` 3. **浏览器兼容**: - 在 `public/index.html` 中添加视口标签确保移动端适配: ```html <meta name="viewport" content="width=device-width,initial-scale=1.0"> ``` ### 备选方案(PostCSS) 可通过 `postcss-pxtorem` 插件全局转换(需在 `postcss.config.js` 中配置): ```js module.exports = { plugins: { &#39;postcss-pxtorem&#39;: { rootValue: 16, propList: [&#39;*&#39;, &#39;!border*&#39;], selectorBlackList: [/^html$/], } } } ``` 此方案会转换所有样式中的 px 单位(包括第三方库),但需注意选择器排除问题[^2]。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值