fangguo-component
v1.1.0
Published
基于 Vue 3 与 Element Plus 的增强组件库,并集成工具函数、自定义指令与组合式函数(Hooks)。
Readme
Fangguo-Component
基于 Vue 3 与 Element Plus 的增强组件库,并集成工具函数、自定义指令与组合式函数(Hooks)。
特性
- Vue 3 + Element Plus:组件与 Element Plus 同栈;
vue、element-plus、tailwindcss等在本包peerDependencies中声明,由业务工程显式安装,构建时作 external,减小包体;其中tailwindcss为 optional peer(仅在使用 Tailwind 时安装),不随本库打入dist,使用方需自行配置 PostCSS(见文档站 安装)。 - 双形态交付:
export *暴露组件、工具、指令与组合式函数(Hooks);default上提供install(app, options?)用于按需全局注册组件/指令,并将工具与 Hooks 命名空间展开在default上(与src/index.ts一致);仅注册组件或仅注册指令时可使用命名导出的installComponents/installDirectives。Hooks 始终建议按需命名导出使用,无需为 Hooks 单独app.use。构建为多入口 ES 模块,可按需import子路径(见package.json的exports与vite多入口配置)。 - 类型与构建:
vite-plugin-dts生成dist下.d.ts;vite-plugin-lib-inject-css将组件样式注入对应 chunk,配合sideEffects声明,便于打包器做 Tree Shaking。 - 文档与开发体验:内置 VitePress 文档站;各模块正文与在线示例(
demos/*.vue)均在src对应目录维护;pnpm docs:gen生成docs下的@include入口;工具模块在无手写 md 时可从源码与 JSDoc 自动生成 API 说明。
项目结构
项目根目录/
├── src/
│ ├── index.ts # 库入口,聚合导出
│ ├── components/ # 组件:每个子目录为一个组件
│ │ └── <单个组件目录>/
│ │ ├── index.ts # 对外导出
│ │ ├── *.vue / *.ts # 实现(按需)
│ │ ├── *.md # 组件文档正文(手写或 AI;docs:gen 只生成 docs 薄入口)
│ │ └── demos/ # 文档站在线示例(可多个 .vue,在 .md 里用 <demo vue="demos/…" />)
│ ├── tools/ # 工具函数:每个子目录为一个工具包
│ │ ├── index.ts # 聚合各工具包导出
│ │ └── <单个工具目录>/
│ │ ├── index.ts # 该包对外 export
│ │ ├── *.ts # 实现文件
│ │ ├── *.md # 可选:手写文档
│ │ └── demos/ # 可选:在线示例(约定同上)
│ ├── directive/ # 自定义指令:每个子目录一条指令包
│ │ ├── index.ts # 聚合导出
│ │ └── <指令子目录>/
│ │ ├── *.ts # 指令实现
│ │ ├── *.md # 可选:指令文档
│ │ └── demos/ # 可选:在线示例(约定同上)
│ ├── hooks/ # 组合式函数:每个子目录一个 Hook 包
│ │ ├── index.ts # 聚合导出
│ │ └── <hook 子目录>/
│ │ ├── *.ts # 实现与 re-export
│ │ ├── *.md # 可选:Hook 文档
│ │ └── demos/ # 可选:在线示例(约定同上)
│ ├── pages/ # 本地 Playground(`pnpm dev`):页面与 mock
│ └── docConfig.ts # 文档站侧边路由分组(人工维护,由 docs/.vitepress/config.ts 引入)
├── docs/ # VitePress 文档站
│ ├── .vitepress/
│ │ ├── config.ts # 站点配置入口
│ │ ├── vueDemoSandboxShared.ts # StackBlitz 等外链沙箱共用依赖
│ │ ├── stackblitzVueTemplates.ts / codesandboxVueTemplates.ts
│ │ ├── theme/ # 主题扩展(如 Element Plus)
│ │ └── dist/ # `pnpm docs:build` 静态站输出
│ ├── guide/ # 指南(安装、快速开始等)
│ ├── index.md # 文档首页(docs:gen 会同步 features 链接)
│ ├── components/ # 脚本生成的 @include 薄入口(勿当作正文仓库)
│ ├── tools/ # 脚本生成的工具文档入口@include 薄入口(勿当作正文仓库)
│ ├── directives/ # 脚本生成的指令文档 @include 薄入口(勿当作正文仓库)
│ └── hooks/ # 脚本生成的 Hooks 文档 @include 薄入口(勿当作正文仓库)
├── CHANGELOG.md # 版本变更记录(文档站「更新日志」页 @include 此文件)
├── ai-skill-docs/ # 给 AI 的撰写规范(Skill 式 Markdown,含组件/工具函数/指令/Hooks/更新日志等约定)
├── scripts/
│ ├── gen-docs.ts # 同步组件/工具/指令/Hooks 文档
│ └── colocatedDemoPlugin.ts # 文档站:将 vue="demos/…" 解析到 src 同目录 demos
└── dist/ # npm 包构建产物:pnpm build:npm 生成,用于发布到 npm(与 docs/.vitepress/dist 不同)注意:以下两段分别为「目录说明」与「文档说明」,参与本库开发前请务必阅读。
目录说明:src/ 下 components、tools、directive、hooks 为平级目录,用途区分如下:components 放 Vue 组件及仅服务于该组件的实现(类型、子模块、工具函数等一律收在对应组件子目录内);tools 放可复用的纯工具函数/算法类代码;directive 放可复用的自定义指令;hooks 放可复用的组合式函数。请勿把某个组件专用才会用到的方法或辅助逻辑塞进 tools 或其它平级目录,避免与对外可复用能力混淆。
文档说明:docs/components、docs/tools、docs/directives、docs/hooks 下的 .md 多为脚本生成的薄入口(一行 @include);正文与在线示例写在 src 对应子目录的 *.md 与 demos/*.vue 中。Markdown 里用 <demo vue="demos/示例.vue" /> 引用同目录 demo;因 VitePress 实际渲染的是 docs 入口,由 scripts/colocatedDemoPlugin.ts 在构建时把路径改写到 src 下的真实文件。新增侧栏条目时需同步维护 src/docConfig.ts。
开发流程(面向组件、工具、指令与 Hooks 的开发者)
pnpm install:安装依赖;运行与类型版本以package.json的peerDependencies为准。- 目录与导出:在
src/components/、src/tools/(子包须含index.ts)、src/directive/、src/hooks/各建一级子目录并实现,自子包index.ts到对应聚合index.ts完成导出,风格与现有一致。(导出名目前未作强制约定,建议对外导出以fg或Fg开头,与库内既有命名习惯一致。) pnpm dev:启动 Playground;在src/pages/写页面与 mock,联调 Element Plus 与 Vue 3(偏交互调试,也可以引入文档站 demo 示例等)。- 各模块
.md文档:正文写在对应子目录的*.md(约定见上文「文档说明」与下文「文档生成说明」)。用 AI 时到ai-skill-docs/,按模块类型@对应 Skill 后再写。 - 在线示例
demos/(可选、可多个):在同目录新建demos/*.vue,在.md中写<demo vue="demos/xxx.vue" title="…" stackblitz />;StackBlitz 外链依赖docs/.vitepress下沙箱模板。可参考src/components/cascader/demos/与cascader.md。 - 更新日志:有对外可见变更时维护根目录
CHANGELOG.md;用 AI 时在ai-skill-docs/选用变更日志相关 Skill 后撰写。 pnpm docs:gen→pnpm docs:dev:docs:gen生成或更新docs下各@include入口,并同步首页features链接;不改写docs/.vitepress/config.ts与src/docConfig.ts(新条目需人工补侧栏)。docs:dev本地预览文档站。pnpm build:npm:构建 npm 发布产物到根目录dist/(发版前执行)。
文档站(VitePress)与相关命令
文档根目录为 docs/;docs/.vitepress/config.ts 与 src/docConfig.ts(侧栏) 由人工维护,pnpm docs:gen 不会覆盖。站点集成 vitepress-demo-plugin 与 colocatedDemoPlugin(解析 vue="demos/…")。更新日志正文在根目录 CHANGELOG.md,docs/guide/changelog.md 仅 @include 引入。
| 命令 | 说明 |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| pnpm docs:dev | 本地启动 VitePress,热更新预览文档 |
| pnpm docs:build | 构建静态站点,输出到 docs/.vitepress/dist(默认) |
| pnpm docs:preview | 预览已构建的文档站 |
| pnpm docs:gen | 扫描 src 四类目录,生成/更新 docs 下 @include 入口并同步首页 features 链接(见下一节;侧栏见 src/docConfig.ts) |
典型流程:改完组件、工具、指令、Hooks 源码或手写 md 后执行 pnpm docs:gen,再 pnpm docs:dev 查看效果;发布文档前执行 pnpm docs:build。
文档生成说明(pnpm docs:gen)
脚本入口:scripts/gen-docs.ts。在 docs/components/、docs/tools/、docs/directives/、docs/hooks/ 下写入或更新各条目的 @include 或(工具无手写 md 时)自动生成 API 式 Markdown;不再生成上述目录下的 index.md 聚合页;并更新首页 docs/index.md 中 features 的链接,使其指向各分类按目录名排序后的第一篇文档。不修改 docs/.vitepress/config.ts 与 src/docConfig.ts。
组件文档
- 扫描
src/components/下一级子目录(排除内部约定的目录名,以脚本中EXCLUDE为准)。 - 组件正文 Markdown 不会由脚本从
.vue/.ts自动生成,需在组件目录下维护.md(可手写或借助 AI 生成),再由docs:gen生成docs/components中的@include入口。 - 在每个组件目录内按优先级查找文档文件:
README.md→index.md→<组件目录名>.md→ 否则取该目录下任意一个.md(按文件名排序取第一个)。 - 在
docs/components/<组件名>.md中生成一行 VitePress 引入,例如:<!--@include: ../../src/components/<组件名>/<上述选中的 md 文件名>-->。 - 侧栏在存在组件时列出各组件条目(无单独的「概览」页);首页
features中「组件」链接与**导航栏「组件」**均指向排序后的第一个组件路由(如/components/cascader)。 - 正文请在源码目录下的对应
.md中维护;docs/components内上述*.md入口由脚本覆盖,不要当作唯一正文仓库。
工具文档
- 扫描
src/tools/下含index.ts的一级子目录(排除脚本中TOOLS_EXCLUDE_DIRS)。 - 若该工具目录内存在可被上述同样规则选中的
.md(README.md/index.md/<工具包名>.md/ 其它.md):在docs/tools/<工具包名>.md中生成@include,指向src/tools/<工具包名>/下选中的那个文件。 - 若不存在任何符合条件的
.md:脚本会根据index.ts中的export … from './…'收集对外暴露的.ts源码,自动解析 JSDoc / 类型并生成整页 API 式文档(无手写 md 时走此分支)。 - 侧栏列出各工具包;不生成
docs/tools/index.md。导航「工具」与首页features中「工具函数」指向排序后的第一个工具路由;清理docs/tools下已移除工具对应的旧.md时会一并删除历史遗留的index.md。
工具侧栏标题会尽量使用手写 md 的一级标题 # …;若无则回退到源码中的 @file、@Description 等注释。
指令文档
- 扫描
src/directive/下一级子目录(排除脚本中DIRECTIVE_EXCLUDE_DIRS,默认含_template)。 - 与组件相同,在子目录内按
README.md→index.md→<子目录名>.md→ 其它.md优先级查找正文;在docs/directives/<子目录名>.md中生成@include,指向src/directive/<子目录名>/下选中的文件。 - 不生成
docs/directives/index.md;侧栏仅列各指令;导航「指令」与首页对应链接指向排序后的第一条指令路由。若无任何带 md 的子目录,则不会生成指令相关导航与侧栏。 - 用 AI 撰写正文时:到
ai-skill-docs/选用与本节(指令)对应的 Skill,在对话中@该文件后再生成。
Hooks(组合式函数)文档
- 扫描
src/hooks/下一级子目录(排除脚本中HOOK_EXCLUDE_DIRS,默认含_template)。 - 与指令相同,在子目录内按
README.md→index.md→<子目录名>.md→ 其它.md优先级查找正文;在docs/hooks/<子目录名>.md中生成@include,指向src/hooks/<子目录名>/下选中的文件。 - 不生成
docs/hooks/index.md;侧栏仅列各 Hook;导航「Hooks」与首页对应链接指向排序后的第一个 Hook 路由。若无任何带 md 的子目录,则不会生成 Hooks 相关导航与侧栏。 - Hooks 不需要全局安装:业务项目按需
import { useXxx } from 'fangguo-component'即可(与src/index.ts命名导出一致)。 - 用 AI 撰写正文时:到
ai-skill-docs/选用与本节(Hooks)对应的 Skill,在对话中@该文件后再生成。
面向在本仓库内开发、构建与维护文档的说明。业务项目如何安装、引入本包,请见文档站内的 安装 与 快速开始。
pnpm install # 安装本仓库依赖
pnpm dev # 启动本地 Playground(组件 / 工具调试)
pnpm build:npm # 构建 npm 发布产物,输出到仓库根目录 dist/
pnpm lint # 代码检查(oxlint)
pnpm lint:fix # 自动修复可修复项
pnpm fmt # 格式化(oxfmt)开发与类型检查建议环境:
- Vue 版本以本仓库
package.json中peerDependencies为准(当前为^3.5.3) - Element Plus、
@element-plus/icons-vue、sass、vue-virtual-scroller、tailwindcss(optional peer,仅在使用 Tailwind 时安装)等同上,以peerDependencies为准;随包安装的dependencies仅crypto-js、lodash-unified(tailwindcss不参与本库产物打包,业务侧自管构建链)
文档相关命令见上文「文档站(VitePress)与相关命令」。
目前遇到的问题(待团队结论)
- 组件库怎么发:走 npm 公共包(
npm publish),还是走私有 org(一般要掏钱)?要不业务直接用git+https/git+ssh指定仓库、某个 tag 装? - 带业务的组件:涉及 store、接口、等等,需要讨论是放到组件库还是?以及如何放到组件库?
- 哪些组件,工具,指令,hook等可以放到组件库里,如何界定?,不能为了使用组件库而过渡放到组件库
- 静态文档dist包需要放到服务器,加上jekins配置,方便使用者查看文档(待做)
