🔥Vite+ElementPlus 自动按需加载与主题定制原理全解析

第一步:安装插件

首先需要安装unplugin-vue-componentsunplugin-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" })],
}),

执行过程:

  1. 解析你模板中的 <el-button>

  2. 自动生成引入语句:

    ts 复制代码
    import { ElButton } from "element-plus";
    import "element-plus/theme-chalk/src/button.scss";
  3. Vite 编译这份 SCSS 时,会应用全局注入配置:

    ts 复制代码
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@use "@/styles/theme.scss" as *;`
        },
      },
    },
  4. 因为组件样式导入了源码,它内部引用的变量 var.scss 会被自定义主题替换。

  5. 构建结果就是:组件颜色来自 $colors.primary.base = #00ac7a 而不是默认蓝色。

相关推荐
老前端的功夫17 分钟前
Vue 3 性能深度解析:从架构革新到运行时的全面优化
javascript·vue.js·架构
天天扭码39 分钟前
如何实现流式输出?一篇文章手把手教你!
前端·aigc·ai编程
前端 贾公子1 小时前
vue移动端适配方案 === postcss-px-to-viewport
前端·javascript·html
GISer_Jing2 小时前
AI营销增长:4大核心能力+前端落地指南
前端·javascript·人工智能
明远湖之鱼2 小时前
一种基于 Service Worker 的渐进式渲染方案的基本原理
前端
前端小端长3 小时前
Vue 中 keep-alive 组件的原理与实践详解
前端·vue.js·spring
FeelTouch Labs3 小时前
Nginx核心架构设计
运维·前端·nginx
雪球工程师团队3 小时前
别再“苦力”写后台,Spec Coding “跑” 起来
前端·ai编程
m0_471199634 小时前
【场景】前端怎么解决离线收银、数据同步异常等场景问题
前端·javascript