第一步:安装插件
首先需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件
ts
yarn add -D unplugin-vue-components unplugin-auto-import
第二步:配置vite.config.ts 按需加载插件
配置好插件,以及指定组件类型声明文件的路径。此后vite每次编译都会生成相应的组件类型文件。
配置完成之后,此时组件就可以自动按需引入了。
需要注意的是代码中不能从element-plus中导入组件,如果导入的话会导致组件样式丢失。
ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
// 按需加载-自动导入
Components({
resolvers: [ElementPlusResolver()],
dts: 'src/typings/components.d.ts' // 指定类型声明文件的路径
}),
AutoImport({
resolvers: [ElementPlusResolver()],
dts: 'src/typings/auto-imports.d.ts'
}),
]
})
第三步:创建scss文件,配置主题
创建theme.scss,这个文件将用于覆盖 Element Plus 的默认样式变量。
使用 @forward 的作用是不要用原来的版本,请转发我这个版本,并用我传入的变量覆盖原变量,通过 with 关键字来覆盖它们。
也就是说你构建了一个新的「var 模块」,它依然暴露和 Element Plus 一样的变量名字,但值已经改成了你自己的主题色。
ts
// element plus 主题配置
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': #00ac7a
)
),
$border-color: (
'': rgba(219, 223, 233, 0.6)
)
);
第四步:vite scss文件编译配置
这个步骤保证了,在编译任何 scss 文件之前,先自动插入这一行。每个组件的 SCSS 文件在编译时都会包含你的自定义变量。
ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
}),
Components({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
}),
],
css: {
preprocessorOptions: {
scss: {
additionalData: `
@use "@/styles/theme.scss" as *;
`,
},
},
},
})
element-plus 的 sass文件编译过程如下
rust
vite -> 加载每个 scss 文件
-> 先执行 @use "@/styles/theme.scss"
↳ @forward element-plus/theme-chalk/src/common/var.scss with ($colors ...自定义... )
-> 编译 element-plus 源码中的 @use 'common/var' as *;
↳发现已经被覆盖 -> 使用新的值
vite配置中 ElementPlusResolver 中 importStyle 的作用
一、背景:Element Plus 的样式有两种版本
Element Plus 每个组件都有两套样式源码:
| 类型 | 路径 | 用途 |
|---|---|---|
| CSS | element-plus/theme-chalk/index.css |
编译好的纯 CSS(不带变量) |
| SASS (SCSS) | element-plus/theme-chalk/src/*.scss |
源代码,包含变量与 mixin,可主题定制 |
当你使用自动按需导入插件 unplugin-vue-components 来加载组件时,插件需要知道:
当引入组件时,它应该加载 哪一套样式?
二、importStyle 的作用
importStyle 控制 Element Plus Resolver 在自动导入组件时,应该引入哪种样式文件。
取值说明:
| 值 | 说明 | 加载的文件 |
|---|---|---|
"css" |
默认值,加载编译好的 CSS 文件 | element-plus/theme-chalk/el-button.css |
"sass" |
加载源码中的 SCSS 文件 | element-plus/theme-chalk/src/button.scss |
三、为什么 "sass" 很重要
如果你写的是:
ts
ElementPlusResolver({ importStyle: "css" })
则每个按需加载的组件都会导入处于最终态的 CSS 文件:
ts
import "element-plus/theme-chalk/el-button.css";
这些文件已经被编译完成,不再包含 Sass 变量,也不会受你的主题配置影响。
但如果你写的是:
ts
ElementPlusResolver({ importStyle: "sass" })
它会导入组件源码对应的 SCSS:
ts
import "element-plus/theme-chalk/src/button.scss";
这些 SCSS 文件仍然保留了对变量模块的引用,例如:
ts
@use 'common/var' as *;
.el-button {
background-color: map.get($colors, 'primary', 'base');
}
👉 这就允许你的 Sass 主题重写变量(@forward)生效。
这也是你能通过 theme.scss 覆盖 Element Plus 主色的关键前提。
四、这段配置在执行时的整体逻辑
ts
Components({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
}),
执行过程:
-
解析你模板中的
<el-button>。 -
自动生成引入语句:
tsimport { ElButton } from "element-plus"; import "element-plus/theme-chalk/src/button.scss"; -
Vite 编译这份 SCSS 时,会应用全局注入配置:
tscss: { preprocessorOptions: { scss: { additionalData: `@use "@/styles/theme.scss" as *;` }, }, }, -
因为组件样式导入了源码,它内部引用的变量
var.scss会被自定义主题替换。 -
构建结果就是:组件颜色来自
$colors.primary.base = #00ac7a而不是默认蓝色。