# 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后,当我们访问时就可以看到全部效果了。