Element Plus 自动导入 CSS 样式

目前 element-plus 如果直接导入组件使用,组件是没有样式的。因为默认不会自动导入 CSS。需要依赖插件。

官方的插件是 unplugin-element-plus 。查看 仓库页面 可以找到针对不同框架的文档。

如果需要自己构建插件,这里提供一种方案。

typescript 复制代码
/**
 * Element Plus 样式按需注入插件
 *
 * 自动检测源码中使用的 Element Plus 组件,并注入对应的 CSS 样式导入。
 * 通过扫描 node_modules/element-plus/es/components 目录建立组件名映射,
 * 确保只注入真实存在的组件样式。
 */
import { readdir } from "node:fs/promises";
import { pascalCase } from "change-case";
import MagicString from "magic-string";
import type { Plugin } from "vite";

/** 组件名映射:PascalCase -> kebab-case(如 ElButton -> button) */
const componentMap = new Map<string, string>();

// 初始化时扫描 Element Plus 组件目录,建立有效组件白名单
const componentsDir = "node_modules/element-plus/es/components";
for (const dir of await readdir(componentsDir, { withFileTypes: true })) {
  if (!dir.isDirectory()) continue;
  componentMap.set(pascalCase(dir.name), dir.name);
}

/** 匹配 El 开头的组件标识符(如 ElButton、ElTable) */
const elComponentRE = /\bEl([A-Z][a-zA-Z0-9]*)\b/g;

/**
 * Element Plus 样式自动注入插件
 *
 * 在 transform 阶段检测源码中使用的 Element Plus 组件,
 * 自动追加对应的 CSS 样式导入语句。
 */
export const elementPlusPlugin: Plugin = {
  name: "element-plus-style",
  enforce: "post",

  transform(code, id) {
    // 跳过 node_modules 中的文件
    if (id.includes("node_modules")) return null;
    // 只处理 .ts 文件和 Vue SFC 的 script 块
    if (!id.endsWith(".ts") && !id.includes("?vue&type=script")) return null;
    if (!code) return null;

    // 收集源码中使用的有效组件名
    const components = new Set<string>();
    for (const match of code.matchAll(elComponentRE)) {
      const [, name] = match;
      if (!componentMap.has(name)) continue;
      components.add(name);
    }
    if (components.size === 0) return null;

    // 生成样式导入语句
    const styleImports = [...components]
      .map((c) => `import 'element-plus/es/components/${componentMap.get(c)}/style/css'`)
      .join("\n");

    // 使用 magic-string 追加导入语句并生成 source map
    const s = new MagicString(code);
    s.append("\n" + styleImports);

    return {
      code: s.toString(),
      map: s.generateMap({ source: id, includeContent: true }),
    };
  },
};

直接在 vite.config.ts 中导入使用即可。至于性能如何,可自行测试。

相关推荐
咪库咪库咪5 小时前
vue3-组件
vue.js
10share5 小时前
100行代码 模拟实现Vue 响应式系统
前端·vue.js
用户4099322502129 小时前
Vue状态管理入门第四章:组合式store和SSR风险
前端·vue.js·后端
锋行天下1 天前
半秒开!还有谁!!!
前端·vue.js·架构
JING小白1 天前
Day 1 重学Vue:响应式系统的“底层逻辑”变更,Vue2旧时代的终结与Vue3新时代的开启
前端·vue.js
OpenTiny社区1 天前
从零开发 AI 聊天页要两周?试试这款 Vue3 垂直对话组件库 TinyRobot,直接开箱即用
前端·vue.js·github
Cobyte1 天前
22.Vue Vapor 组件 props 的实现
前端·javascript·vue.js
白雾茫茫丶1 天前
探索 Nuxt.js 全栈能力:用 Better-Auth 打造类型安全的 RBAC 权限系统
前端·vue.js·nuxt.js
向阳而生6601 天前
文件上传也能玩出花?Vue3 教你优雅实现“选择文件”和“选择文件夹”🚀
vue.js
3630458411 天前
Signal 带来的架构问题思考
前端·vue.js