# ProCheckBox 复选框组件

<cite>
**本文引用的文件**
- [packages/components/ProCheckBox.vue](file://packages/components/ProCheckBox.vue)
- [packages/core/src/components/ProCheckBox.vue](file://packages/core/src/components/ProCheckBox.vue)
- [src/views/ProCheckbox.vue](file://src/views/ProCheckbox.vue)
- [packages/libs/request.js](file://packages/libs/request.js)
- [packages/libs/util.js](file://packages/libs/util.js)
- [packages/components/index.js](file://packages/components/index.js)
- [packages/index.js](file://packages/index.js)
- [package.json](file://package.json)
- [README.md](file://README.md)
</cite>

## 更新摘要
**变更内容**
- 新增全局映射配置功能，支持通过 $PRO_IVIEW 全局配置统一管理数据映射设置
- 更新 mergedMap 计算属性，支持多级优先级的数据映射配置
- 扩展组件配置灵活性，允许在应用级别统一设置默认映射规则

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
ProCheckBox 是基于 Vue 3 + View UI Plus 的高级复选框组件，支持从远程接口或本地数组动态生成选项，具备多选/单选模式、首项自动选择、模板化标题渲染、字符串与数组值类型的灵活切换等能力。该组件常用于表格行选择、批量操作、筛选条件等场景。

**更新** 新增全局映射配置功能，通过 $PRO_IVIEW 全局配置对象统一管理数据映射设置，提供更灵活的配置方式。

## 项目结构
本仓库采用多包架构，ProCheckBox 组件位于核心组件目录，并通过统一入口导出与安装。示例页面演示了其在实际业务中的用法。

```mermaid
graph TB
subgraph "示例应用"
Demo["示例视图<br/>src/views/ProCheckbox.vue"]
end
subgraph "组件库"
Index["入口导出<br/>packages/index.js"]
CompIndex["组件索引<br/>packages/components/index.js"]
CheckBox["ProCheckBox 组件<br/>packages/components/ProCheckBox.vue"]
CoreCheckBox["核心实现<br/>packages/core/src/components/ProCheckBox.vue"]
Request["请求封装<br/>packages/libs/request.js"]
Util["工具函数<br/>packages/libs/util.js"]
GlobalConfig["全局配置<br/>$PRO_IVIEW"]
end
Demo --> CheckBox
Index --> CompIndex
CompIndex --> CheckBox
CheckBox --> Request
CheckBox --> Util
CheckBox --> GlobalConfig
CoreCheckBox -. 复制实现 .- CheckBox
```

**图表来源**
- [packages/index.js:12-42](file://packages/index.js#L12-L42)
- [packages/components/index.js:6-22](file://packages/components/index.js#L6-L22)
- [packages/components/ProCheckBox.vue:1-158](file://packages/components/ProCheckBox.vue#L1-L158)
- [packages/core/src/components/ProCheckBox.vue:1-144](file://packages/core/src/components/ProCheckBox.vue#L1-L144)
- [packages/libs/request.js:1-78](file://packages/libs/request.js#L1-L78)
- [packages/libs/util.js:1-110](file://packages/libs/util.js#L1-L110)

**章节来源**
- [README.md:15](file://README.md#L15)
- [packages/index.js:12-42](file://packages/index.js#L12-L42)
- [packages/components/index.js:6-22](file://packages/components/index.js#L6-L22)

## 核心组件
- 组件名称：ProCheckBox
- 技术栈：Vue 3 JSX + View UI Plus CheckboxGroup/Checkbox/Icon
- 主要职责：
  - 动态加载选项列表（远程请求或本地数组）
  - 渲染可选/已选状态的复选框集合
  - 支持多选与单选模式
  - 值类型控制（数组/字符串）
  - 首项自动选择
  - 模板化标题展示
  - **全局映射配置支持**

**章节来源**
- [packages/components/ProCheckBox.vue:6](file://packages/components/ProCheckBox.vue#L6)
- [packages/core/src/components/ProCheckBox.vue:6](file://packages/core/src/components/ProCheckBox.vue#L6)

## 架构总览
ProCheckBox 的运行时架构由"数据源""渲染层""状态管理""全局配置"四部分组成。数据源支持本地数组或远程请求；渲染层负责将数据映射为复选框项；状态管理通过 v-model 实现双向绑定，并根据 multiple/valueType 控制输出格式；全局配置通过 $PRO_IVIEW 提供统一的映射设置。

```mermaid
sequenceDiagram
participant U as "用户"
participant C as "ProCheckBox 组件"
participant GC as "全局配置<br/>$PRO_IVIEW"
participant R as "请求封装<br/>request.js"
participant V as "View UI Plus<br/>CheckboxGroup/Checkbox"
U->>C : "设置属性request/list/map/multiple/valueType"
C->>C : "init()/mounted() 触发初始化"
C->>GC : "获取全局映射配置"
GC-->>C : "返回全局 map 设置"
alt 使用本地列表
C->>C : "直接使用 list 作为 innerList"
else 使用远程请求
C->>R : "customRequest({ request })"
R-->>C : "返回数据"
C->>C : "按 dataPath 提取列表"
end
C->>V : "渲染 CheckboxGroup/Checkbox 列表"
U->>V : "勾选/取消勾选"
V-->>C : "innerValue 变化"
C-->>U : "通过 update : modelValue 输出值数组或字符串"
```

**图表来源**
- [packages/components/ProCheckBox.vue:60-75](file://packages/components/ProCheckBox.vue#L60-L75)
- [packages/libs/request.js:39-77](file://packages/libs/request.js#L39-L77)

## 详细组件分析

### 属性与配置
- request
  - 类型：字符串或对象
  - 作用：远程请求地址或配置对象，用于拉取选项列表
  - 注意：与 list 互斥，二者只能选其一
- list
  - 类型：数组
  - 作用：本地静态选项列表，优先于 request 生效
- multiple
  - 类型：布尔
  - 默认：true
  - 作用：是否多选；非多选时仅输出最后一个选中项
- first
  - 类型：布尔
  - 默认：false
  - 作用：当初始值为空时，自动选择第一项并触发 input/change 事件
- map
  - 类型：对象
  - 默认：{}
  - 作用：局部数据路径映射配置
    - dataPath：从响应体提取列表的路径
    - titlePath：标题字段路径，支持 ES6 模板字符串如 "${field}" 进行组合显示
    - valuePath：绑定到 v-model 的值字段路径
- modelValue
  - 类型：任意
  - 作用：当前选中值（受 multiple/valueType 影响）
- valueType
  - 类型：字符串
  - 可选："string"
  - 作用：强制输出为字符串（逗号分隔）

**更新** 新增全局映射配置支持，通过 $PRO_IVIEW 全局配置提供默认映射设置。

**章节来源**
- [packages/components/ProCheckBox.vue:32-62](file://packages/components/ProCheckBox.vue#L32-L62)
- [packages/core/src/components/ProCheckBox.vue:32-62](file://packages/core/src/components/ProCheckBox.vue#L32-L62)

### 全局映射配置机制
- 配置来源优先级
  1. 组件局部配置（map）
  2. 全局配置（$PRO_IVIEW.map）
  3. 默认值（"data"/"title"/"value"）
- 配置结构
  - dataPath：数据列表路径，默认 "data"
  - titlePath：标题路径，默认 "title"
  - valuePath：值路径，默认 "value"
- 应用方式
  - 通过 mergedMap 计算属性统一处理配置优先级
  - 在组件初始化和数据获取时使用统一的映射规则

```mermaid
flowchart TD
Start(["组件初始化"]) --> GetLocal["获取局部 map 配置"]
GetLocal --> CheckGlobal{"是否存在 $PRO_IVIEW.map?"}
CheckGlobal --> |是| MergeGlobal["合并全局 map 配置"]
CheckGlobal --> |否| UseDefault["使用默认配置"]
MergeGlobal --> CheckLocal{"局部配置是否完整?"}
CheckLocal --> |是| UseLocal["使用局部配置"]
CheckLocal --> |否| UseGlobal["使用全局配置"]
UseLocal --> Finalize["生成最终 mergedMap"]
UseGlobal --> Finalize
UseDefault --> Finalize
Finalize --> Apply["应用到数据获取和渲染"]
```

**图表来源**
- [packages/components/ProCheckBox.vue:60-75](file://packages/components/ProCheckBox.vue#L60-L75)

**章节来源**
- [packages/components/ProCheckBox.vue:60-75](file://packages/components/ProCheckBox.vue#L60-L75)

### 渲染与数据流
- 渲染逻辑
  - 使用 CheckboxGroup 包裹一组 Checkbox
  - 每个 Checkbox 的 label 来自 item[valuePath]
  - 标题内容来自 getExpText(item)，支持普通路径或 ES6 模板字符串
  - 若 item.icon 存在，渲染对应图标
- 数据映射
  - 当未指定 dataPath 时，直接使用请求返回结果作为列表
  - titlePath 支持模板表达式，内部通过工具函数进行安全求值
  - **全局映射配置统一管理 dataPath/titlePath/valuePath**
- 值绑定
  - 通过 computed.innerValue 实现 v-model 的 get/set
  - get：将字符串值按逗号拆分为数组
  - set：根据 multiple/valueType 决定输出类型（数组或字符串）

```mermaid
flowchart TD
Start(["初始化"]) --> CheckList{"是否存在 list?"}
CheckList --> |是| UseLocal["使用本地 list 作为 innerList"]
CheckList --> |否| CheckRequest{"是否存在 request?"}
CheckRequest --> |是| Fetch["调用 customRequest 获取数据"]
Fetch --> Extract["按 dataPath 提取列表"]
Extract --> SetList["赋值给 innerList"]
CheckRequest --> |否| EndInit["无数据源，innerList 为空"]
UseLocal --> FirstCheck{"first 为真且初始值为空?"}
SetList --> FirstCheck
FirstCheck --> |是| AutoSelect["选择第一项并触发 input/change"]
FirstCheck --> |否| Render["渲染 Checkbox 列表"]
EndInit --> Render
AutoSelect --> Render
```

**图表来源**
- [packages/components/ProCheckBox.vue:75-96](file://packages/components/ProCheckBox.vue#L75-L96)
- [packages/libs/util.js:4-19](file://packages/libs/util.js#L4-L19)

**章节来源**
- [packages/components/ProCheckBox.vue:7-25](file://packages/components/ProCheckBox.vue#L7-L25)
- [packages/components/ProCheckBox.vue:68-74](file://packages/components/ProCheckBox.vue#L68-L74)
- [packages/libs/util.js:4-19](file://packages/libs/util.js#L4-L19)

### 事件与状态管理
- 输入事件
  - input：当选中首项且 first 为真时触发
  - change：当选中首项且 first 为真时触发
- 输出事件
  - update:modelValue：通过 computed.innerValue.set 触发，输出最终值
- 状态管理
  - innerValue：计算属性，负责 v-model 的读写
  - isStringType：根据 valueType 或当前 modelValue 类型决定是否为字符串模式

**章节来源**
- [packages/components/ProCheckBox.vue:90-96](file://packages/components/ProCheckBox.vue#L90-L96)
- [packages/components/ProCheckBox.vue:101-122](file://packages/components/ProCheckBox.vue#L101-L122)

### 全选与半选机制
- 全选
  - 当 multiple 为 true 且所有项均被选中时，v-model 将包含全部值
- 半选
  - 当 multiple 为 true 且部分项被选中时，v-model 为部分值数组
- 单选
  - 当 multiple 为 false 时，v-model 仅包含最近一次选中的值
- 字符串输出
  - 当 valueType 为 "string" 或当前值为字符串时，输出为逗号分隔的字符串

**章节来源**
- [packages/components/ProCheckBox.vue:110-121](file://packages/components/ProCheckBox.vue#L110-L121)

### 请求与工具函数
- 请求封装
  - 支持字符串 URL、对象配置、函数回调三种形式
  - 自动注入 Token 头部，支持路径变量替换与 GET/POST 参数抽取
- 模板解析
  - 支持 titlePath 中的 ES6 模板语法，安全地从数据项中取值
  - 对非法标识符抛出错误，避免运行时异常

**章节来源**
- [packages/libs/request.js:39-77](file://packages/libs/request.js#L39-L77)
- [packages/libs/util.js:4-19](file://packages/libs/util.js#L4-L19)

### 在表格中的集成与批量操作
- 行选择列
  - 在表格列配置中添加一个自定义列，使用 ProCheckBox 绑定行数据的唯一标识字段
  - 通过 v-model 绑定选中项数组，实现多行勾选
- 批量操作
  - 读取选中数组长度，结合后端接口实现批量删除、批量更新等操作
  - 结合 ProTable 的搜索/分页能力，确保批量操作针对当前筛选与页码范围内的数据

```mermaid
sequenceDiagram
participant T as "表格列"
participant CB as "ProCheckBox"
participant VM as "父组件数据模型"
T->>CB : "传入 { list, map, modelValue }"
CB-->>VM : "update : modelValue(选中项数组)"
VM->>VM : "根据选中数组执行批量操作"
VM-->>T : "刷新表格/提示操作结果"
```

[此图为概念性流程示意，无需图表来源]

## 依赖关系分析
- 组件依赖
  - lodash-es：数据处理与路径访问
  - axios：HTTP 请求
  - view-ui-plus：CheckboxGroup/Checkbox/Icon
- 组件注册
  - 通过 packages/components/index.js 导出 ProCheckBox
  - 通过 packages/index.js install 时全局注册
- 全局配置
  - 通过 $PRO_IVIEW 全局属性提供统一配置
  - 支持 map 和 format 两种配置类型
- 版本与脚本
  - package.json 定义了构建脚本与依赖版本

```mermaid
graph LR
Pkg["package.json 依赖"] --> Lodash["lodash-es"]
Pkg --> AxiosDep["axios"]
Pkg --> VueDep["vue"]
Pkg --> ViewUIDep["view-ui-plus"]
IndexMain["packages/index.js"] --> GlobalConfig["全局配置<br/>$PRO_IVIEW"]
GlobalConfig --> CheckBox["ProCheckBox.vue"]
CheckBox --> Lodash
CheckBox --> AxiosDep
CheckBox --> ViewUIDep
```

**图表来源**
- [package.json:20-32](file://package.json#L20-L32)
- [packages/index.js:12-42](file://packages/index.js#L12-L42)
- [packages/components/index.js:6-22](file://packages/components/index.js#L6-L22)

**章节来源**
- [package.json:20-32](file://package.json#L20-L32)
- [packages/index.js:12-42](file://packages/index.js#L12-L42)
- [packages/components/index.js:6-22](file://packages/components/index.js#L6-L22)

## 性能考虑
- 列表渲染
  - 使用 map 遍历 innerList 渲染，建议控制列表规模或启用虚拟滚动（如需）
- 请求缓存
  - 可在外层缓存请求结果，避免重复请求相同 URL
- 字符串拆分
  - 字符串到数组的拆分发生在 get 中，频繁切换会带来额外开销，建议在上层合并变更
- 模板解析
  - titlePath 的模板解析仅在标题渲染时发生，注意模板复杂度
- **全局配置优化**
  - 通过 $PRO_IVIEW 统一配置减少重复设置
  - 避免在多个组件中重复定义相同的映射规则

[本节为通用建议，无需章节来源]

## 故障排查指南
- 无法显示选项
  - 检查 request 是否正确，确认 dataPath 是否指向列表
  - 若使用本地 list，请确认数据结构符合预期
  - **检查 $PRO_IVIEW 全局配置是否正确设置**
- 值类型不符合预期
  - multiple 为 false 时仅输出单值；valueType 为 "string" 时输出逗号分隔字符串
- 首项未自动选择
  - first 为真时要求初始值为空；若已有值则不会自动选择
- 标题模板报错
  - 检查 titlePath 中的变量名是否合法，避免非法标识符导致解析失败
- 请求失败
  - 检查网络与跨域设置；确认 Token 注入逻辑与服务端一致
- **全局配置不生效**
  - 确认 $PRO_IVIEW 全局配置是否正确挂载到 Vue 实例
  - 检查配置格式是否符合预期（map 对象结构）

**章节来源**
- [packages/components/ProCheckBox.vue:75-96](file://packages/components/ProCheckBox.vue#L75-L96)
- [packages/libs/util.js:4-19](file://packages/libs/util.js#L4-L19)
- [packages/libs/request.js:39-77](file://packages/libs/request.js#L39-L77)

## 结论
ProCheckBox 提供了灵活的选项加载、多样化的值绑定与输出控制，适用于多种交互场景。通过合理的 map 配置与事件监听，可轻松实现表格行选择与批量操作。**新增的全局映射配置功能进一步提升了组件的灵活性和可维护性，通过 $PRO_IVIEW 统一管理配置减少了重复设置，建议在复杂场景下配合虚拟滚动与请求缓存优化性能。**

## 附录

### 快速使用示例（路径参考）
- 示例页面：[src/views/ProCheckbox.vue:1-48](file://src/views/ProCheckbox.vue#L1-L48)
- 组件实现：[packages/components/ProCheckBox.vue:1-158](file://packages/components/ProCheckBox.vue#L1-L158)
- 核心实现复制：[packages/core/src/components/ProCheckBox.vue:1-144](file://packages/core/src/components/ProCheckBox.vue#L1-L144)

### 全局配置设置示例
```javascript
// 在应用初始化时设置全局配置
Vue.use(ProComponents, {
  pro_iview: {
    map: {
      dataPath: "data.list",
      titlePath: "${name}",
      valuePath: "id"
    }
  }
});
```

### 安装与注册（路径参考）
- 全局安装：[packages/index.js:12-42](file://packages/index.js#L12-L42)
- 组件导出：[packages/components/index.js:6-22](file://packages/components/index.js#L6-L22)