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

相关推荐
A黄俊辉A5 天前
uniapp webview中实现 app和内嵌的H5双向通信
vue.js·json
honkun65 天前
vue 表格组件 vxe-table 配置 ajax 请求自动加载数据与表单查询
vue.js·vxe-table
kybs19915 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
雪芽蓝域zzs5 天前
第26章:ECharts 自定义主题 + 页面一键切换主题(深色 / 浅色两套)
vue.js·echars
雪芽蓝域zzs5 天前
第22章:ECharts 图表联动(多图表交互联动)
vue.js·echars
daols885 天前
vue 表格组件 vxe-table 实现虚拟滚动与无需滚动加载
vue.js·vxe-table
雪芽蓝域zzs5 天前
第18章:ECharts 折线图 + 标记点、标记线,自定义 tooltip
vue.js·echars
雪芽蓝域zzs5 天前
第24章:ECharts 地图组件(基础行政区地图,若依 Vue3)
vue.js·echars
计算机毕设定制辅导-无忧学长5 天前
《基于Vue的流浪动物救助中心管理系统的设计与实现》
java·vue.js·spring boot·流浪动物救助中心管理系统
雪芽蓝域zzs5 天前
第25章:地图下钻交互(点击省份,切换到对应省份城市地图)
vue.js·echars