下面详细介绍 Element Plus 源码中 packages 目录下的各个子目录及其作用。Element Plus 采用 monorepo 管理,每个子包都有明确的职责,理解这些目录对改造或借鉴其结构至关重要。
bash
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 组件,每个组件是一个独立的子目录,支持按需加载。
结构示例:
python
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 规范,支持主题变量定制。
结构:
csharp
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:处理尺寸属性
结构:
perl
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:焦点陷阱(用于弹窗)
结构:
arduino
directives/
├── click-outside/
│ └── index.ts
├── repeat-click/
│ └── index.ts
└── index.ts # 统一注册所有指令
改造要点:
- 可修改指令逻辑、修改指令名称(注意全局前缀替换)。
- 删除不需要的指令,并在
directives/index.ts中移除。
6. locale/ -- 国际化语言包
作用:提供多语言支持,包含所有组件的文字(如弹窗的"确定/取消"、分页的"上一页/下一页"等)。
结构:
python
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 组件库。