根据官方文档,按需引入配合babel-plugin-component
使用,然后将.babelrc修改为:
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
复制代码
我们还可以自定义的去覆盖element-ui的scss样式变量,来修改主题颜色。创建element-variables.scss
/* 改变主题色变量 */
$--color-primary: #912;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
复制代码
然后在main.js文件中导入element-variables.scss:
import { Button } from 'element-ui'
import '@/assets/style/element-variables.scss'
Vue.component(Button.name, Button)
复制代码
但是现在有一个问题是,通过这种方式修改主题打包出来的css非常大。但是如果注释掉该语句样式又不会起作用,这是非常让人懊恼的。
通过下图,我们可以知道其实babel-plugin-component
是生效了的。但是app.[hash].css
的体积十分巨大,里面包含了element-ui的所有样式,甚至和chunk-vendors.[hash].css
中的样式有重复的部分。
追其原因还是因为在babel-plugin-component
中默认使用的是lib
文件夹进行打包,但是在lib文件夹中样式文件是css文件,使我们没办法通过仅仅只是修改scss样式变量的覆盖方式来做到动态的去更改主题色。这就是为什么如果我们注释了@import "~element-ui/packages/theme-chalk/src/index";
语句,自定义主题就不生效了的原因,我们前面重新定义的样式变量其实为了覆盖index.scss
文件中的变量,再通过重新生成新的样式去覆盖原有的样式文件来做到自定义主题的效果。
但是我们可以通过修改babel-plugin-component
配置+全局导入样式变量的方式来实现真正的样式的按需加载。
修改.babelrc文件:
{
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
[
'component',
{
'libraryName': 'element-ui',
// 默认情况下,libDir的默认是lib文件夹
'libDir': 'packages',
// scss文件是放在packages/theme-chalk/src下的
'styleLibraryName': 'theme-chalk/src',
'ext': '.scss'
}
]
]
}
复制代码
这时候,就可以实现按需引入的是scss了,然后我们在配置全局scss变量。
修改element-variables.scss文件,只保留变量:
/* 改变主题色变量 */
$--color-primary: #912;
/* 改变 icon 字体路径变量,必需 */
// $--font-path: '~element-ui/lib/theme-chalk/fonts';
// @import "~element-ui/packages/theme-chalk/src/index";
复制代码
配置vue.config.js文件:
{
css: {
loaderOptions: {
scss: {
prependData: [
'@import "src/assets/style/element-variables.scss";',
// 非必须
// 这里引入element-ui本身的变量,是因为其他样式文件可能会用到它本身的变量
// 但是在自定义变量文件中又没有做覆盖定义
'@import "~element-ui/packages/theme-chalk/src/common/var.scss";'
].join('')
}
}
}
}
复制代码
在main.js中可以不需要像开始那样引入自定义主题样式了:
import { Button } from 'element-ui'
// import '@/assets/style/element-variables.scss'
Vue.component(Button.name, Button)
复制代码
打包效果: