# MapGIS-WebClient-Vue3 **Repository Path**: osmapgis/mapgis-webclient-vue3 ## Basic Information - **Project Name**: MapGIS-WebClient-Vue3 - **Description**: 基于Vue3的MapGIS Web客户端产品 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: 10.7.8.10 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-03-06 - **Last Updated**: 2026-03-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
基于 Vue 3 + Vite + TypeScript 的组件库。
## 一、特性 - 开箱即用的高质量 Vue 3组件 - 丰富的文档和示例 - 采用流行的技术栈 ## 二、深入了解 ### 2.1 代码结构 ```text ├── .husky // git辅助工具 ├── .vscode // 工作区配置目录 ├── scripts // 脚本资源 ├── templates // 组件模板 ├── packages // 组件库目录 │ ├── ui // ui组件库 │ ├── components // 组件库源码 │ ├── package.json // 项目清单文件(不发布) │ ├── docs // VitePress API文档 │ ├── package.json // 项目清单文件(不发布) │ ├── entrance // 组件库入口 │ ├── package.json // 项目清单文件(发布) │ ├── examples // 示例程序 │ ├── package.json // 项目清单文件(不发布) │ ├── hooks // 可复用的功能 │ ├── package.json // 项目清单文件(不发布) │ ├── storybook // 组件故事书 │ ├── package.json // 项目清单文件(不发布) │ ├── utils // 工具包 │ ├── package.json // 项目清单文件(不发布) │ ├── deploy.bat // 组件库资源部署脚本 │ ├── publish.bat // 组件库发布脚本 │ ├── common // common组件库 │ ├── ... // 同ui库 │ ├── leaflet // leaflet组件库 │ ├── ... // 同ui库 │ ├── mapboxgl // mapboxgl组件库 │ ├── ... // 同ui库 │ ├── cesium // cesium组件库 │ ├── ... // 同ui库 ├── package.json // 项目清单文件(不发布) ├── pnpm-workspace.yaml // pnpm工作空间文件 ``` - 可以看到在一个组件库包中,只有entrance包是被允许发布的,其他包都是禁止发布的 - 组件工具包可以被其他组件库共用 - 组件示例程序引用的是组件库源码包,支持组件开发调试 - 组件文档引用的是组件库源码包,支持组件开发调试 - 组件故事引用的是entrance包打包后的组件库,支持生产环境下测试 ### 2.2 环境准备 本项目是一个基于pnpm的单体多包仓库,只支持pnpm包管理器,请先确保是否已经安装pnpm > Node.js版本要求18以上 ``` # npm安装pnpm npm i -g pnpm # yarn安装pnpm yarn global add pnpm ``` ### 2.3 开发 ```shell # 安装 pnpm install # 运行组件库ui项目示例 pnpm ui:serve # 打包组件库ui pnpm ui:build # 运行组件库ui地图故事 pnpm ui:storybook # 运行组件库ui文档 pnpm ui:docs:dev ``` ### 2.4 内置命令 以ui组件库为例: ```shell # 创建组件 pnpm cc # 通过git交互式提交代码,建议通过此命名进行提交 pnpm commit # ui组件发布到公共仓库npmmjs ui:publish # ui组件库发布到私有仓库11.130 ui:publish:private # ui组件库资源部署 ui:deploy # ui组件库示例项目运行,同ui:server ui:dev # ui组件库示例项目运行 ui:serve # ui组件库示例项目打包 ui:examples:build # ui组件库示例项目打包预览 ui:examples:preview # ui组件库示例项目仅预览,需先前已打过包 ui:examples:preview-only # ui组件库打包 ui:build # ui组件库单元测试 ui:test # ui组件库覆盖率测试 ui:test:coverage # ui组件库故事运行,会先进行组件库打包 ui:storybook # ui组件库故事仅运行,需先前已打过包 ui:storybook-only # ui组件库故事打包,会先进行组件库打包 ui:storybook:build # ui组件库故事仅打包 ui:storybook:build-only # ui组件库故事预览,会先进行故事打包 ui:storybook:preview # ui组件库故事仅预览,需先前已打过包 ui:storybook:preview-only # ui组件库文档运行 ui:docs:dev # ui组件库文档打包 ui:docs:build # ui组件库文档预览,会进行文档打包 ui:docs:preview # ui组件库文档仅预览,需先前已打过包 ui:docs:preview-only # 格式化文档 prettier # 进行TypeScript类型检查,分析类型错误 type-check # 代码质量检查,是否符合ESLINT规则 lint # 检查并修复错误 lint:fix # 安装前钩子 preinstall # 修改记录生成 changelog ``` ## 三、技术栈 | 类别 | 技术 | 说明 | | ---------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 核心框架与语言 | Vue3 | 作为基础框架,提供响应式系统和组件化开发能力 | | | TypeScript | 用于增强类型安全,提升代码可维护性 | | 构建和工具链 | Vite | 主流构建工具,提供快速的冷启动和热更新 | | | pnpm | 作为高效的包管理工具,用于依赖管理和Monorepo架构,通过**物理存储优化**解决资源浪费问题,通过**依赖隔离机制**保障代码安全,通过**原生Workspace支持**提升协作效率 | | 测试和质量保障 | Vitest | 基于Vite的单元测试框架 | | | ESLint/Prettier | 代码规范和格式化工具,确保代码风格统一 | | | Husky | 用于在Git钩子中集成代码质量检查和自动化格式化任务,确保每次提交的代码都符合规范 | | | Commitlint | 标准化提交规范框架:提供Git提交标准化框架,通过适配器扩展交互逻辑,需搭配适配器使用 | | | pretty-quick | 与Husky搭配在提交代码前自动格式化更改的文件,按需触发Prettier,仅处理Git变更文件并集成到开发流程 | | | czg | 交互式命令行工具,用于生成标准化的Git提交信息,以符合Commitlint等规范,Commitizen CLI替代品,内置cz-git适配器的独立工具,优化启动速度和工程化体验 | | 状态管理与路由 | Pinia | 替代Vuex的轻量级状态管理库 | | | Vue Router | 处理前端路由,常用于复杂单页应用 | | UI组件库与设计 | Ant Design Vue 4.x | 适用于企业级中后台项目 | | | LESS | CSS预处理工具,支持变量、嵌套、混合等特性 | | | CSS变量 | 实现运行时主题切换 | | | BEM | Block Element Modifier,块元素修饰符命名方法,代码不仅更具结构性,而且也更易于理解每个部分的关系和作用。这有助于团队协作开发,减少样式冲突,并提高代码的整体质量 | | 文档与示例 | VitePress | 基于Vite的新一代静态网站生成器 | | | Example展示页面 | 提供实际组件使用的例子 | | | Storybook | 用于组件展示和测试 | | 辅助工具与扩展库 | Handlebars | JavaScript 的页面模板库 | | 架构 | Monorepo | 采用pnpm workspace管理多包组件库,统一仓库管理,共享依赖与构建流程 | ## 四、组件规范(最佳实践) **高效、复用!!!** - 能自动化的就不要手动 - 能复用的就不要重复编写 ### 4.1 单个组件文件含义 以xxx组件为例: ```text ├── __tests // 组件的测试文件夹,存放组件的测试文件 │ ├── index.spec.tsx // 测试文件,默认提供组件的CSS类测试,一般只有一个测试文件 ├── examples // 组件示例文件夹 │ ├── basic.vue // 基本用法示例,一个组件可以有多个示例文件,按用法命名,可以被引用到文档、故事中 ├── stories // 组件故事 │ ├── xxx.stories.ts // 组件故事文件,以kebab-case方式命名,一般只有一个故事文件 ├── style // 组件样式文件夹 │ ├── index.less // 样式文件,符合LESS规范和BEM架构,可使用基于AntD的CSS变量,一般只有一个样式文件 ├── xxx.vue // 组件文件,组合模板、逻辑和样式 ├── index.ts // 组件入口文件,集中导出组件或功能,实现外部按需引入 ├── instance.ts // 组件实例类型声明文件,当父组件通过ref引用子组件时,可约束该引用的类型 ├── types.ts // 组件类型声明文件,定义组件Props、Emit等核心接口,确保类型一致性 ├── use-xxx.ts // 组件业务逻辑文件,采用组合式函数写法,被xxx.vue使用,支持复用 ``` > 文件名以kebab-case命名,组件名以PascalCase命名 ### 4.2 组件的关联组件文件含义 关联组件表示功能强关联、高频同时使用,比如Button和ButtonGroup组件,这里以xxx的关联组件xxx-yyy组件为例: ```diff ├── __tests // 组件的测试文件夹 │ ├── index.spec.tsx // 测试文件,增加xxx-yyy组件的单元测试【必须】 ├── examples // 组件示例文件夹 │ ├── basic.vue // 基本用法示例,可增加xxx-yyy组件的组合示例【可选】 + │ ├── xyz.vue // 关于xxx-yyy组件用法示例【可选】 ├── stories // 组件故事 │ ├── xxx.stories.ts // 组件故事文件,增加xxx-yyy组件的故事【必须】 ├── style // 组件样式文件夹 │ ├── index.less // 样式文件,增加xxx-yyy组件的样式定义【必须】 ├── xxx.vue // 组件文件 + ├── xxx-yyy.vue // xxx-yyy组件文件【必须】 ├── index.ts // 组件入口文件,增加xxx-yyy的组件安装和导出【必须】 ├── instance.ts // 组件实例类型声明文件,增加xxx-yyy组件的实例类型声明【必须】 ├── types.ts // 组件类型声明文件,增加xxx-yyy的组件类型声明【必须】 ├── use-xxx.ts // 组件业务逻辑文件 + ├── use-xxx-yyy.ts // 组件业务逻辑文件【必须】 ``` ### 4.2 多个组件的结构定义 以components组件包为例: ```text ├── aaa // 组件aaa ├── bbb // 组件bbb ├── ccc // 组件目录ccc │ ├── lll // 组件目录ccc下面的组件lll │ ├── mmm // 组件目录ccc下面的组件mmm ├── ddd // 组件ddd │ ├── ppp // 组件ddd的子组件ppp │ ├── qqq // 组件ddd的子组件目录qqq │ ├── uuu // 组件ddd的子组件目录qqq下面的组件uuu │ ├── vvv // 组件ddd的子组件目录qqq下面的组件uuu ├── components.ts // 组件注册和导出,支持全量注册和按需注册 ├── index.ts // 组件入口,组件导出,包括组件类型声明和组件业务逻辑 ``` - 支持平级式和内聚式组件结构,按功能的耦合度来选择不同的方,比如aaa和bbb就是平级式、ddd和ppp就是内聚式 - 支持组件目录,可定义在父组件内部,对子组件进行分类 - 所有的组件需在components.ts中形成组件列表进行注册并具名导出 - 所有的组件需在index.ts中进行导出,包括组件自身的任何导出 > 建议:实际开发时,不要过深的层次结构,能散在根目录下的就不要归类到目录中,能在父组件下形成子组件列表的就要再进行分类 ## 五、新增组件(组件结构和展示) 新增组件前需要对组件做好设计,包括组件名、在组件库中的结构、组件的属性、事件、组件的UI等 ### 5.1 手动新增 **以组件my-com为例:** 1. 复制aaa组件的源码到components目录下或某个组件分类或某个父组件下,这里我们假设放置到components的**my-dir**目录下 2. 将含有aaa的文件修改为实际组件名的kebab-case形式my-com,涉及到以下文件: ```text # 直接修改 stories/aaa.stories.ts -> stories/my-com.stories.ts aaa.vue -> my-com.vue use-aaa.ts -> use-my-com.vue ``` 3. 同步修改文件名变化引起的导入,涉及到以下文件: ```text __tests__/index.spec.tsx my-com.vue index.ts instance.ts ``` 4. 修改组件名Aaa为新增组件的PascalCase形式MyCom,涉及到以下文件: ```text __tests__/index.spec.tsx my-com.vue index.ts instance.ts ``` 5. 修改样式类aaa为my-com,涉及到以下文件: ```text __tests__/index.spec.tsx style/index.less my-com.vue ``` 6. 统一修改其他Aaa为PascalCase形式MyCom 7. 统一修改其他aaa为camelCase形式myCom 8. 修改`components/components.ts`,添加组件引入、形成新的组件列表,并导出该组件 ```diff ... + import MyCom from './my-com' const components: Plugin[] = [ ..., + MyCom ] export { ..., + MyCom } ... ``` 9. 修改`components/index.ts`,导出组件 ```diff ... + export * from './my-com' ... ``` 10. 添加组件文档 组件文档项目基于VitePress编写,所有的组件文档都在组件库的docs项目内,其目录结构如下: ```text ├── .vitepress // VitePress主题和配置目录 │ ├── components // 组件配置 │ ├── zh.json // 中文版组件列表配置 │ ├── config // VitePress配置目录 │ ├── en.mts // 英文版配置,包括导航条和侧边栏配置 │ ├── index.mts // 配置入口,集成其他配置 │ ├── shared.mts // 公共配置,与语言无关 │ ├── zh.mts // 中文版配置,包括导航条和侧边栏配置 │ ├── theme // VitePress主题目录,可在此目录内引入组件,配置主题和全局样式 ├── api // 保留的组件英文版文档目录,内部结构与zh目录相同 ├── examples // 保留的组件用法示例,目前用法示例均在组件内部,此处暂保留 ├── public // 静态资源 │ ├── images // 保留的图片静态资源,当文档中有图片需要展示时,可将图片放到此目录内 ├── zh // 组件中文版文档目录 │ ├── api // api文档目录 │ ├── components // 组件部分的文档,结构与组件结构一致 │ ├── guide // 开发指南部分的文档,包括介绍、安装和快速上手 │ ├── other // 其他部分的文档,包括更新日志和常见问题 │ ├── index.md // 首页内容 ├── index.md // 英文版首页内容 ``` 在`zh/api/components`目录下按照新增组件的同结构创建以组件kebab-case命名的md文档,内容可复制于aaa.md,然后修改里面与组件名称、用法路径相关的内容 这里按照前面的示例,我们需要创建文档`zh/api/components/my-dir/my-com.md` ```markdown # MyCom 介绍。 > `` ## 基本用法 :::api ## API ### 属性 | 参数 | 说明 | 类型 | 默认值 | 版本 | | ---- | ---- | ---- | ------ | ---- | ### 事件 | 事件名称 | 说明 | 回调参数 | 版本 | | -------- | ---- | -------- | ---- | ### 方法 | 名称 | 描述 | 版本 | | ---- | ---- | ---- | ::: ``` 在左侧导航条中增加组件菜单,修改`.vitepress/components/zh.json`: ```json [ { "text": "MyDir", "collapsed": false, "base": "/api/components/my-dir/", "items": [ { "text": "MyCom", "link": "my-com" } ] } ] ``` > ⚠️⚠️⚠️ 请仔细检查每一处修改!!!务必遵守规范!!! ### 5.2 自动新增(推荐) 可以看到,每次新增组件就需要手动修改大量的地方,非常的繁琐,还容易遗忘和出错。 本项目提供了基于Handlebars引擎的组件模板,可通过命名`pnpm cc`交互式的进行组件创建,上面的N多步骤一键搞定!!! ``` PS E:\MapGIS-WebClient-Vue3> pnpm cc > @mapgis/components-workspace@ cc E:\MapGIS-WebClient-Vue3 > node scripts/component-generator.js ? 组件名称(PascalCase): MyCom ? 组件模块(如ui等模块): ui ? 组件目录(相对组件模块components目录,默认为空): my-dir ✔ 生成: __tests__/index.spec.tsx ✔ 生成: E:\MapGIS-WebClient-Vue3\ui\docs\zh\api\components\my-dir/my-com.md ✔ 生成: examples/basic.vue ✔ 生成: stories/my-com.stories.ts ✔ 生成: style/index.less ✔ 生成: my-com.vue ✔ 生成: index.ts ✔ 生成: instance.ts ✔ 生成: types.ts ✔ 生成: use-my-com.ts 组件生成成功!路径: ui\components\my-dir\my-com ``` - 组件名称:务必输入PascalCase形式的组件名称 - 组件模块:默认是ui,可输入cesium、common、mapboxgl、leaflet等 - 组件目录:相对组件模块components目录,默认为空,如果输入my-dir,则组件代码将放入到my-dir下面,如果需要增加地图组件的子组件,我们需要输入此目录,将代码放到地图组件的内部 对`components/components.ts`和`components/index.ts`的修改采用了占位符的方式,请千万要保持占位符的内容不变,否则组件创建命令会提示错误!!! **components/components.ts** ```js // 🛑🛑🛑 AUTO_IMPORT_PLACEHOLDER - DO NOT DELETE OR MODIFY 🛑🛑🛑 const components: Plugin[] = [ // 🛑🛑🛑 AUTO_COMPONENTS_PLACEHOLDER - DO NOT DELETE OR MODIFY 🛑🛑🛑 ] export { // 🛑🛑🛑 AUTO_EXPORT_PLACEHOLDER - DO NOT DELETE OR MODIFY 🛑🛑🛑 // prettier-ignore } ``` **components/index.ts** ```js // 🛑🛑🛑 AUTO_EXPORT_PLACEHOLDER - DO NOT DELETE OR MODIFY 🛑🛑🛑 ``` ### 5.3 新增组件初次测试 此时,我们仅仅是按照组件规范完成了组件代码的初步编写。 当我们执行`pnpm ui:storybook`的时候,已经可以在组件故事的左侧看到我们新增的组件故事了。 当我们执行`pnpm ui:docs:dev`的时候,也可以在组件文档的左侧看到我们新增的组件文档了。 > 以ui组件库为例,新增组件后,虽然组件故事和组件文档可以展示,但是当我们执行yarn ui:dev时不会有效果,因为示例项目中没有增加对该组件的示例 ### 5.4 展示组件示例 组件库的examples是针对组件的示例项目,可以在此项目中增加示例的集成展示。 **以ui组件为例:** 需要修改`examples/assets/components.json`文件,增加对该示例的配置。 > 其他组件库的示例项目均需要按照自己项目的规范进行添加 ```diff [ { "id": "base", "name": "基础", "groups": [ { "id": "Overview", "name": "概览" }, + { + "id": "MyCom", + "name": "我的组件" + } ] } ] ``` > ui组件库的示例项目,会根据配置的组件id和组件name,去自动按照组件id指向的组件名称去寻找组件基本用法示例,即组件结构内examples/basic.vue的内容 运行命令`pnpm ui:dev`可以看到新增的组件示例了,当我们修改组件结构内examples/basic.vue的内容时,示例效果也会跟随变化。 ### 5.5 新增组件综合测试 至此,组件基本用法示例在示例项目、组件文档和组件故事中都可以展示了,可通过如下命令进行确认: 这里仍然以ui组件库为例: ```shell # ui组件库示例项目运行,同ui:server pnpm ui:dev # ui组件库示例项目运行 pnpm ui:serve # ui组件库示例项目打包 pnpm ui:examples:build # ui组件库示例项目打包预览 pnpm ui:examples:preview # ui组件库示例项目仅预览,需先前已打过包 pnpm ui:examples:preview-only # ui组件库打包 pnpm ui:build # ui组件库单元测试 pnpm ui:test # ui组件库覆盖率测试 pnpm ui:test:coverage # ui组件库故事运行,会先进行组件库打包 pnpm ui:storybook # ui组件库故事仅运行,需先前已打过包 pnpm ui:storybook-only # ui组件库故事打包,会先进行组件库打包 pnpm ui:storybook:build # ui组件库故事仅打包 pnpm ui:storybook:build-only # ui组件库故事预览,会先进行故事打包 pnpm ui:storybook:preview # ui组件库故事仅预览,需先前已打过包 pnpm ui:storybook:preview-only # ui组件库文档运行 pnpm ui:docs:dev # ui组件库文档打包 pnpm ui:docs:build # ui组件库文档预览,会进行文档打包 pnpm ui:docs:preview # ui组件库文档仅预览,需先前已打过包 pnpm ui:docs:preview-only ``` ## 六、组件开发(组件逻辑和文档示例) 进入到此部分,需要确保组件已经创建,并且创建的组件能够在示例项目、文档项目和故事项目中都得到正确的展示,如果还未完成,请参考第五部分进行完成,并且要确保组件已事先做好了设计,下面的部分是按照设计进行开发实现。 ### 6.1 定义组件属性和事件 修改组件内部的types.ts文件,增加对外的属性和事件,并补充好注释内容,此内容**需要**同步到组件文档的API部分,请确保二者务必一致,以CollapseButton组件为例: ```js import { isBoolean } from '@mapgis/webclient-vue3-ui-utils' import type { ExtractPropTypes } from 'vue' export const collapseButtonProps = { /** * @description 折叠方向,位于被折叠区域的位置 */ direction: { type: String, validator(value) { return ['left', 'right', 'top', 'bottom'].includes(value) }, default: 'right' }, /** * @description 折叠状态 */ collapsed: { type: Boolean, default: false }, /** * @description 层叠顺序 */ zIndex: { type: Number, default: 1 } } export const collapseButtonEmits = { 'update:collapsed': (collapsed: boolean) => isBoolean(collapsed), change: (collapsed: boolean) => isBoolean(collapsed) } export type CollapseButtonProps = ExtractPropTypes export type CollapseButtonEmits = typeof collapseButtonEmits ``` - 上面对于每个属性都明确了类型 - 对于取值在某些值域范围内的需要进行校验 - 有默认值的需要提供默认值 - 如果该属性是双向绑定的,需要在事件中添加以update开头的事件 - 每个事件都需要进行参数校验 与之对应的组件文档API部分的内容如下: **属性** | 参数 | 说明 | 类型 | 默认值 | 版本 | | ------------------ | ------------------------------ | ------------------------ | ------ | ---- | | direction | 折叠方向,位于被折叠区域的位置 | left\|right\|top\|bottom | right | | | collapsed(v-model) | 折叠状态 | boolean | false | | | zIndex | 层叠顺序 | number | 1 | | **事件** | 事件名称 | 说明 | 回调参数 | 版本 | | -------- | ---------- | --------- | ---- | | change | 变化时回调 | collapsed | | ### 6.2 编写组件业务逻辑 在组件的组合式函数use文件中,基于定义组件属性、事件,编写组件的业务逻辑,导出相应的数据和方法,在Vue3中,我们需要谨慎分析使用ref和reactive,确保响应式符合我们的期望 - 使用属性,直接采用props.xxx,当监控属性变化时,需采用watch(() => props.xxx, val => {})写法 - 获取reactive定义的原生内容采用toRaw() - 获取全部插槽,采用useSlots() ### 6.3 编写组件文件 组件模板默认创建了以mapgis开头,组件名kebab-case方式的CSS类(ui组件中间多了一个-ui),新增CSS类的时候,需要符合BEM架构,以下是集中常用的方法: ```text // 块,以my-com的ui组件为例,形成mapgis-ui-my-com的CSS类 ns.b() // 修饰,形成mapgis-ui-my-com--open的CSS类,修饰通过--连接 ns.m('open') // 元素,形成mapgis-ui-my-com__item的CSS类,元素通过__连接 ns.e('item') // 元素的修饰,形成mapgis-ui-my-com__item--actived的CSS类 ns.em('item', 'actived') ``` 在组件脚本部分调用组合式函数后,需要解构导出的数据和方法,同时我们需要仔细分析是否符合响应式需求,原则上,我们的业务逻辑都是写在use开头的组合式函数中,组件文件中更多的是组件模板的内容,但是像ref()的使用则必须在组件文件中使用,然后再传入到业务逻辑模块中 ```text ``` ### 6.4 编写组件样式 修改`style/index.less`,参照BEM规范进行编写,前面的my-com组件的样式示例如下: ```lesss .mapgis-ui-my-com { &--open { } &__item { &--actived { } } } ``` **CSS变量的使用** 整个组件库项目依赖的是Ant Design Vue 4.x的基础UI组件库,但是Ant Design Vue 4.x移除了LESS支持,采用的CSS-in-JS的写法,所以MapGIS的ui组件库将AntD的设计令牌动态转成了CSS变量,将SeedToken、MapToken、AliasToken的名称转成kebab-case形式后,增加了--mapgis前缀。比如: ```text borderRadius -> var(--mapgis-border-radius) colorBgBase -> var(--mapgis-color-bg-base) colorPrimary -> var(--mapgis-color-primary) colorTextBase -> var(--mapgis-color-text-base) ``` 更多Token可参考:[https://antdv.com/docs/vue/customize-theme-cn#api](https://antdv.com/docs/vue/customize-theme-cn#api) 当我们想对项目的样式添加相关的内容时,可参考如下: ```less .mapgis-ui-my-com { background-color: var(--mapgis-color-bg-base) &--open { border: 1px solid var(--mapgis-color-border); } &__item { &--actived { color: var(--mapgis-color-primary); } } } ``` 在ui组件库的示例项目中提供了主题切换的功能,依靠这套CSS变量,我们可以在Ant Design设计令牌的基础上**打造我们的视觉方案**。 ### 6.5 增加关联组件(可选) 当该组件有强关联的组件时,可以直接在该组件目录内新增关联组件内容,可参考《4.2 组件的关联组件文件含义》进行编写。 ### 6.6 完善组件示例 组件功能开发完毕后,需要进行测试,有条件的可以在`__tests__`中添加组件单元测试用例,目前我们先将重点放到由示例项目examples构建的测试框架中,不同组件库的examples项目不同,既可以设计成一个完整的系统,也可以设计成独立的示例单元,但是不管怎么样,示例用法期望能够在组件文档和组件故事中复用,避免重复开发,当前ui组件库的示例项目会自动获取组件库内的基本用法示例,并按照assets/components.json的配置进行组装。 组件库内部的`examples/basic.vue`是基本用法示例,我们可以为它编写更多高级的用法示例, ```vue ``` 尽量保持用法示例的独立性,里面依赖的自研组件和AntD组件都会在示例项目、文档项目和故事项目中进行全量注册。 ### 6.7 完善组件文档 位于docs项目下与组件结构一致的组件文档,需要按照组件的设计进行补充,包括组件的**用法部分**和组件的**API部分**,是文档的重点内容,其中**API部分**要与**组件的属性和事件**保持一致,未来有**调整的属性和事件我们还需要对版本列进行维护**。组件的用法部分,默认引用了组件的基本用法,我们可以根据需要进行增加,以实际指导二次开发用户学习为目标,提高示例的可用性和覆盖度!!! ``` ## 基本用法 ## 尺寸 ## 对齐方式 ``` 像上述内容就表示提供了三种用法示例。 ### 6.8 完善组件故事 组件故事是另一种展示组件文档和示例的方式,当前我们借助组件故事,更多的是展示组件的示例和用法,还没有加入更多可在线测试的交互式体验方式,在当前复用组件用法示例的基础上,需要我们给示例提供属性参数,并将参数控件化,未来有时间的话可以慢慢补充。 组件故事文件直接位于组件的结构内,在stories目录内,我们可以与组件examples下的用法示例提供一致的故事列表,如下就展示了两个组件故事: ```js import type { Meta, StoryObj, ArgTypes } from '@storybook/vue3' import Basic from '../examples/basic.vue' import Size from '../examples/size.vue' import basicCode from '../examples/basic.vue?raw' import sizeCode from '../examples/size.vue?raw' const meta: Meta = { title: '组件/MyCom', tags: ['autodocs'], argTypes: {} } export default meta type Story = StoryObj & { argTypes?: ArgTypes } export const BasicStory: Story = { name: '基本用法', args: {}, parameters: { docs: { source: { code: basicCode, language: 'js' } } }, render: args => ({ components: { Basic }, setup() { return { args } }, template: ` ` }) } export const SizeStory: Story = { name: '大小', args: {}, parameters: { docs: { source: { code: sizeCode, language: 'js' } } }, render: args => ({ components: { Size }, setup() { return { args } }, template: ` ` }) } ``` 参照模板很轻松就可以增加更多的故事了。 ### 6.9 增加组件静态资源 组件内的静态资源我们直接放到components项目内,组件外的静态资源需要在示例项目、文档项目和故事项目都需要的可统一放到组件库examples/public下,项目各自的静态资源请放到各自的public内部,以下是一个组件库项目所拥有的静态资源目录,说明了哪些是公共的,哪些是私有的,以ui组件库为例: ```text ├── components // 组件源码包 │ ├── aaa // 组件aaa │ ├── xxx.png // 组件内的静态资源 │ ├── yyy.json // 组件内的静态资源 ├── docs // 文档项目 │ ├── public // 文档项目私有的静态资源 ├── examples // 示例项目 │ ├── public // 公共的静态项目 + 示例项目私有的静态资源 ├── storybook // 故事项目 │ ├── public // 故事项目私有的静态资源 ``` ## 七、组件发布和部署 ### 7.1 组件发布 当组件开发到了一个迭代版本需要发布时,可优先发布到私有仓库进行充分测试验证后,再发布到公共仓库,各组件库内置了`publish.bat`发布脚本,支持传入`private`参数用于区分环境,并且在根package.json中提供了`ui:publish`和`ui:publish:private`命令,辅助我们更加方便地执行此操作。 ### 7.2 组件部署 当组件示例、文档和故事需要部署时,需要对各个子项目进行打包构建,在组件示例中集成了文档和故事的连接,当他们部署在一起的时候,可快捷地进行跳转,各组件库内置了`deploy.bat`脚本,支持传入服务器的ip,辅助我们快速地将打包后的资源推送到该服务器上。 以ui组件库为例,会将静态资源全部发送到远程服务器的`MapGIS-WebClient-Vue3-UI`共享目录内,在该目录内会形成如下结构: ```text ├── examples // 组件库示例项目静态资源 ├── docs // 组件库文档项目静态资源 ├── storybook // 组件库故事项目静态资源 ``` 我们在服务器上可通过Nginx对静态资源进行发布,可在Nginx的配置文件nginx.conf中增加如下内容: ```js server { listen 8888; location /vue3/ui/examples { index index.html; alias D:/MapGIS-WebClient-Vue3-UI/examples; try_files $uri $uri/ /vue3/ui/examples/index.html; } location /vue3/ui/docs { index index.html; alias D:/MapGIS-WebClient-Vue3-UI/docs; try_files $uri $uri/ /vue3/ui/docs/index.html; } location /vue3/ui/storybook { index index.html; alias D:/MapGIS-WebClient-Vue3-UI/storybook; try_files $uri $uri/ /vue3/ui/storybook/index.html; } location @router { rewrite ^.*$ /dist/index.html last; } } ``` 重启Nginx后,当我们访问时就可以看到全部效果了。