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 中导入使用即可。至于性能如何,可自行测试。

相关推荐
sugar__salt5 小时前
Vue3 表单双向绑定与响应式核心 API 技术详解
前端·javascript·vue.js
郝亚军6 小时前
使用Vue 3和Nginx打包和部署Vue.js项目的一般步骤
前端·vue.js·nginx
阿懂在掘金8 小时前
企业级命令式弹窗方案:三行代码适配已有 Dialog
前端·vue.js·前端框架
YWL8 小时前
OpenLayers + Vue 2 使用指南(01)
前端·javascript·vue.js
达子6669 小时前
第8章_HarmonyOs开发图解 剪贴板
vue.js
森林的尽头是阳光10 小时前
tree回显问题
javascript·vue.js·elementui
qetfw12 小时前
MWU:Vue 3 + FastAPI 的 MaaFramework 跨平台 WebUI 源码
前端·vue.js·python·fastapi·开源项目·效率工具
mfxcyh12 小时前
Vue3+Ant Design Vue 实现手动异步文件上传(含大小校验、弹窗上传)
前端·javascript·vue.js
meilindehuzi_a12 小时前
Vue3进阶基础:指令修饰符、v-model表单绑定、动态样式、计算属性与侦听器实战
前端·javascript·vue.js
csdn2015_12 小时前
vue 前端运行命令
前端·javascript·vue.js