ElementPlus 源码之 packages 目录

37 阅读6分钟

下面详细介绍 Element Plus 源码中 packages 目录下的各个子目录及其作用。Element Plus 采用 monorepo 管理,每个子包都有明确的职责,理解这些目录对改造或借鉴其结构至关重要。

packages/
├── components/          # 所有 UI 组件(每个组件独立文件夹)
├── theme-chalk/         # 样式系统(SCSS 源码、变量、主题)
├── hooks/               # 可复用的组合式 API(Composition API)
├── utils/               # 工具函数(类型判断、DOM 操作、事件等)
├── directives/          # 自定义指令(v-click-outside 等)
├── locale/              # 国际化语言包
├── element-plus/        # 组件库入口包(整合所有模块并导出)
├── icons-vue/           # 图标库(Vue 组件形式)
├── icons/               # 图标原始资源(SVG 等)
└── test-utils/          # 测试辅助工具(内部使用)

下面逐一详细说明。


1. components/ – 核心 UI 组件

作用:存放所有 Vue 组件,每个组件是一个独立的子目录,支持按需加载。

结构示例

components/
├── button/
│   ├── src/
│   │   ├── button.vue      # 组件模板与逻辑
│   │   ├── button.ts       # 组件定义(install、props 类型)
│   │   └── types.ts        # TypeScript 接口
│   ├── index.ts            # 导出组件及 install 方法
│   └── style/              # 样式入口(指向 theme-chalk)
├── input/
├── dialog/
└── index.ts                # 全局导出所有组件

改造要点

  • 需要修改组件逻辑或 DOM 结构时,直接编辑这里的具体组件文件。
  • 删除不需要的组件:直接删除对应文件夹,并更新 components/index.ts 中的导出列表。

2. theme-chalk/ – 样式系统(SCSS)

作用:使用 SCSS 编写组件样式,遵循 BEM 规范,支持主题变量定制。

结构

theme-chalk/
├── src/
│   ├── common/
│   │   └── var.scss        # 全局设计令牌(颜色、字体、间距等)
│   ├── mixins/
│   │   ├── config.scss     # 命名空间、BEM mixin
│   │   ├── mixins.scss     # 通用 mixin(清除浮动、圆角等)
│   │   └── utils.scss      # 工具类 mixin
│   ├── button.scss         # 单个组件样式
│   ├── input.scss
│   └── index.scss          # 入口:导入所有组件样式
├── gulpfile.ts             # 构建脚本(编译 SCSS → CSS)
└── package.json

改造要点

  • 修改 var.scss 中的 $--el-* 变量可全局换肤。
  • 修改 mixins/config.scss 中的 $namespace 可改变所有 CSS 类名前缀(如 el-my-)。
  • 删除不需要的组件样式:在 index.scss 中注释掉对应的 @import

3. hooks/ – 可复用的组合式 API

作用:抽取组件中的通用逻辑,以 Vue Composition API 形式提供,提升代码复用性。这些 hooks 通常不依赖具体组件,可被多个组件调用。

常见 hooks

  • use-attrs:透传非 props 属性
  • use-click-outside:监听点击外部
  • use-locale:国际化相关逻辑
  • use-namespace:生成 BEM 类名
  • use-z-index:管理层级
  • use-size:处理尺寸属性

结构

hooks/
├── use-attrs/
│   └── index.ts
├── use-click-outside/
│   └── index.ts
└── index.ts               # 统一导出

改造要点

  • 如果你的新组件需要类似的逻辑,可以直接引用这些 hooks。
  • 也可以修改现有 hooks 以适应新的前缀或行为(如 use-namespace 可改变生成的类名前缀)。

4. utils/ – 工具函数

作用:提供与 UI 无关的纯函数,用于数据类型判断、DOM 操作、事件处理、错误提示等。这些函数被组件和 hooks 广泛使用。

分类

  • dom.ts:DOM 操作(添加类、获取滚动条位置等)
  • types.ts / typescript.ts:类型判断(isString, isObject 等)
  • error.ts:抛出组件错误
  • event.ts:事件相关(点击、滚动静默等)
  • aria.ts:无障碍辅助
  • position.ts:定位计算

改造要点

  • 一般无需大改,除非你希望改变底层工具行为(例如自定义错误格式)。
  • 可增加自己的工具函数,放在 utils/ 下并导出。

5. directives/ – 自定义指令

作用:存放 Vue 自定义指令,例如监听点击外部、重复点击防抖、权限控制等。

常见指令

  • v-click-outside:点击元素外部触发回调
  • v-repeat-click:处理长按重复点击
  • v-resize:监听元素尺寸变化
  • v-trap-focus:焦点陷阱(用于弹窗)

结构

directives/
├── click-outside/
│   └── index.ts
├── repeat-click/
│   └── index.ts
└── index.ts               # 统一注册所有指令

改造要点

  • 可修改指令逻辑、修改指令名称(注意全局前缀替换)。
  • 删除不需要的指令,并在 directives/index.ts 中移除。

6. locale/ – 国际化语言包

作用:提供多语言支持,包含所有组件的文字(如弹窗的“确定/取消”、分页的“上一页/下一页”等)。

结构

locale/
├── lang/
│   ├── zh-cn.ts
│   ├── en.ts
│   ├── ja.ts
│   └── ...
├── index.ts               # 语言管理核心(提供 useLocale、t 函数)
└── format.ts              # 模板字符串格式化

改造要点

  • 如果需要新增语言,在 lang/ 下添加文件并在 index.ts 中注册。
  • 修改现有翻译内容。
  • 如果你移除了某些组件,需要同步删除语言包中对应的词条,否则毫无影响。

7. element-plus/ – 组件库入口包

作用:将上述所有模块整合在一起,暴露最终的组件库。这才是用户安装 element-plus npm 包后实际引入的内容。

关键文件

  • index.ts:导出所有组件、指令、插件、locale 等,并提供 install 方法。
  • defaults.ts:全局配置(如组件尺寸、命名空间、z-index 基数)。
  • make-installer.ts:生成安装器,支持按需加载。
  • package.json:定义包的名称、入口文件、导出映射(exports 字段)。

改造要点

  • 修改 package.json 中的 name 为你自己的包名(如 my-ui-lib)。
  • 修改 index.ts 中的导出内容——如果删除了某些组件,就不要在这里导出。
  • 修改 defaults.ts 中的全局默认行为(如 namespace 可改为你的前缀)。

8. icons-vue/icons/

  • icons-vue/:将图标库以 Vue 组件形式提供,每个图标是一个独立的 .vue 文件,支持按需加载。
  • icons/:存放原始 SVG 图标资源,通常用于生成 icons-vue

如果你的组件库不需要内置图标,可以直接删除这两个目录,并在 element-plus/index.ts 中移除相关导出。


9. test-utils/ – 测试辅助

作用:内部使用的测试工具函数,例如模拟鼠标事件、创建 Vue 测试实例等。packages/components 中的组件测试会依赖它。

改造要点

  • 如果保留组件测试,则保留此目录;否则可删除。

总结:各目录职责与改造时的典型操作

目录核心职责大范围重写时的主要操作
components/Vue 组件实现修改/删除/新增组件、调整 props 与事件
theme-chalk/SCSS 样式改主题变量、改类名前缀($namespace)、删除无用样式
hooks/逻辑复用修改命名空间、调整通用行为
utils/工具函数一般不改,必要时增加自己的工具
directives/自定义指令修改指令逻辑、删除无用指令
locale/国际化语言增删语言、修改翻译文本
element-plus/组件库入口修改包名、导出内容、全局配置(如 namespace
icons-vue/图标组件可保留、替换或删除

理解这些目录的分工,就是掌握了 Element Plus 的架构精髓。在改造时,你可以根据需要保留、修改或完全重写某个子包,最终构建出属于自己的 UI 组件库。