# 通用工具函数

<cite>
**本文引用的文件**
- [packages/index.js](file://packages/index.js)
- [packages/libs/util.js](file://packages/libs/util.js)
- [packages/libs/request.js](file://packages/libs/request.js)
- [packages/core/src/libs/util.js](file://packages/core/src/libs/util.js)
- [packages/core/src/libs/request.js](file://packages/core/src/libs/request.js)
- [packages/core/src/locale/format.js](file://packages/core/src/locale/format.js)
- [src/main.js](file://src/main.js)
</cite>

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

## 简介
本文件为通用工具函数库的参考文档，聚焦于以下能力：
- 数据处理工具：数组与对象操作、数据校验与清理
- 类型判断与转换：基础类型检查、复杂类型识别、字符串到函数的转换
- 字符串处理工具：模板替换、格式化、序列化与反序列化
- 工具函数的分类索引与使用示例：涵盖 Lodash-es 的集成与扩展
- 在组件中的使用方式与最佳实践
- 性能优化建议、兼容性说明与扩展开发指南

## 项目结构
该工具库主要分布在 packages 目录下，核心工具集中在 libs 与 core/src/libs 中，并通过 packages/index.js 暴露为插件形式供应用集成。

```mermaid
graph TB
subgraph "packages"
A["index.js<br/>插件入口与全局注入"]
subgraph "libs"
U["util.js<br/>字符串模板/序列化/函数转换/HTML标签检测/空值清理"]
R["request.js<br/>请求封装与URL占位替换"]
end
subgraph "core/src/libs"
CU["util.js<br/>与 libs/util.js 同名但独立实现"]
CR["request.js<br/>与 libs/request.js 同名但独立实现"]
end
end
subgraph "应用"
M["src/main.js<br/>插件安装与全局属性注入"]
end
M --> A
A --> U
A --> R
A --> CU
A --> CR
```

**图表来源**
- [packages/index.js:1-69](file://packages/index.js#L1-L69)
- [packages/libs/util.js:1-110](file://packages/libs/util.js#L1-L110)
- [packages/libs/request.js:1-78](file://packages/libs/request.js#L1-L78)
- [packages/core/src/libs/util.js:1-110](file://packages/core/src/libs/util.js#L1-L110)
- [packages/core/src/libs/request.js:1-78](file://packages/core/src/libs/request.js#L1-L78)
- [src/main.js:1-14](file://src/main.js#L1-L14)

**章节来源**
- [packages/index.js:1-69](file://packages/index.js#L1-L69)
- [src/main.js:1-14](file://src/main.js#L1-L14)

## 核心组件
- 插件入口与全局注入：在插件安装时，向全局注入 HTTP 客户端、日期库、Lodash 实例以及配置项，同时注册全局组件与指令。
- 工具函数模块：
  - 字符串模板与序列化：支持安全的模板替换、对象序列化（含函数与 undefined 的处理）、反序列化（含渲染函数的动态恢复）。
  - 请求封装：统一处理 URL 占位替换、请求方法选择、参数抽取、请求头注入（如 Token）。
  - 类型辅助：HTML 标签检测、空值清理、字符串到函数的通用转换。
- 国际化格式化：提供字符串模板格式化工具，支持位置参数与命名参数两种调用方式。

**章节来源**
- [packages/index.js:12-42](file://packages/index.js#L12-L42)
- [packages/libs/util.js:4-110](file://packages/libs/util.js#L4-L110)
- [packages/libs/request.js:39-78](file://packages/libs/request.js#L39-L78)
- [packages/core/src/locale/format.js:23-46](file://packages/core/src/locale/format.js#L23-L46)

## 架构总览
插件安装流程将第三方库与项目工具函数整合，形成统一的全局能力，供组件与业务逻辑使用。

```mermaid
sequenceDiagram
participant App as "应用实例"
participant Plugin as "packages/index.js"
participant Util as "packages/libs/util.js"
participant Req as "packages/libs/request.js"
App->>Plugin : 调用 app.use(ProComponents)
Plugin->>Plugin : 初始化全局属性($http/$dayjs/$lodash/$PRO_IVIEW)
Plugin->>Plugin : 注册全局组件与指令
Plugin-->>App : 安装完成
App->>Util : 使用模板/序列化/函数转换
App->>Req : 发起请求(自动URL替换/参数抽取/头注入)
```

**图表来源**
- [packages/index.js:12-42](file://packages/index.js#L12-L42)
- [packages/libs/util.js:4-110](file://packages/libs/util.js#L4-L110)
- [packages/libs/request.js:39-78](file://packages/libs/request.js#L39-L78)

## 详细组件分析

### 字符串模板与序列化工具
- 功能要点
  - 模板替换：支持 ${...} 占位符，进行变量提取与安全访问；对非法标识符抛出异常。
  - 对象序列化：将函数与 undefined 转换为可持久化字符串，避免丢失。
  - 对象反序列化：从字符串重建函数与对象，必要时注入 Vue 渲染上下文以支持渲染函数。
  - 字符串到函数：支持传入函数或字符串表达式，统一转换为可执行函数。
  - HTML 标签检测：内置常见 HTML 标签名集合，用于类型判断。
  - 空值清理：移除错误对象中的空值并维护对象完整性。

```mermaid
flowchart TD
Start(["进入模板替换"]) --> Match["匹配 ${...} 占位符"]
Match --> HasVar{"存在变量名？"}
HasVar --> |否| Empty["返回空字符串"]
HasVar --> |是| Validate["校验变量名合法性"]
Validate --> Valid{"合法？"}
Valid --> |否| Throw["抛出异常"]
Valid --> |是| GetVal["从上下文中取值"]
GetVal --> Replace["替换占位符"]
Replace --> End(["返回结果"])
Throw --> End
Empty --> End
```

**图表来源**
- [packages/libs/util.js:4-19](file://packages/libs/util.js#L4-L19)

**章节来源**
- [packages/libs/util.js:4-110](file://packages/libs/util.js#L4-L110)
- [packages/core/src/libs/util.js:4-110](file://packages/core/src/libs/util.js#L4-L110)

### 请求封装与 URL 占位替换
- 功能要点
  - 支持三种调用形态：字符串 URL、对象配置、直接函数。
  - 自动 URL 占位替换：将 ${key} 替换为数据中的对应值。
  - 参数抽取：根据方法自动将字段抽取到 params 或 data。
  - 请求头注入：从查询参数中提取 token 并注入 Authorization。
  - 全局 HTTP 客户端：优先使用全局 $http，否则回退到默认客户端。

```mermaid
sequenceDiagram
participant Caller as "调用方"
participant Req as "request.js"
participant Axios as "$http/Axios"
Caller->>Req : 传入 {request, method, keys, datas, headers}
Req->>Req : 解析 request 形态(字符串/对象/函数)
Req->>Req : URL 占位替换(replactUrl)
Req->>Req : 参数抽取(pick)
Req->>Req : 头注入(getHeaders)
Req->>Axios : 发起请求
Axios-->>Req : 返回响应
Req-->>Caller : 响应结果
```

**图表来源**
- [packages/libs/request.js:39-78](file://packages/libs/request.js#L39-L78)

**章节来源**
- [packages/libs/request.js:1-78](file://packages/libs/request.js#L1-L78)
- [packages/core/src/libs/request.js:1-78](file://packages/core/src/libs/request.js#L1-L78)

### 类型判断与转换工具
- HTML 标签检测：基于预置标签集合判断是否为合法 HTML 标签。
- 空值清理：递归清理错误对象中的空值，保持结构简洁。
- 字符串到函数：统一处理函数与字符串表达式，支持上下文绑定与返回值标准化。

```mermaid
flowchart TD
S(["输入: 格式描述/值"]) --> IsFn{"是否函数？"}
IsFn --> |是| CallFn["直接调用函数(value)"]
IsFn --> |否| IsStr{"是否字符串？"}
IsStr --> |是| BuildFn["构造函数(value)并执行"]
IsStr --> |否| Fallback["返回 false"]
CallFn --> Ret["返回结果"]
BuildFn --> Ret
Fallback --> Ret
```

**图表来源**
- [packages/libs/util.js:57-78](file://packages/libs/util.js#L57-L78)

**章节来源**
- [packages/libs/util.js:80-110](file://packages/libs/util.js#L80-L110)

### 国际化字符串格式化
- 功能要点
  - 支持位置参数与命名参数两种模板语法。
  - 特殊转义：连续大括号用于输出字面量。
  - 缺省值处理：未提供的参数返回空字符串。

```mermaid
flowchart TD
T(["调用 template(str, ...args)"]) --> ArgsOne{"参数为对象？"}
ArgsOne --> |是| UseObj["使用对象作为映射"]
ArgsOne --> |否| UseList["使用数组作为映射"]
UseObj --> Replace["按 %{} 或 {key} 替换"]
UseList --> Replace
Replace --> Escape["处理连续大括号"]
Escape --> Out["返回结果"]
```

**图表来源**
- [packages/core/src/locale/format.js:23-46](file://packages/core/src/locale/format.js#L23-L46)

**章节来源**
- [packages/core/src/locale/format.js:1-50](file://packages/core/src/locale/format.js#L1-L50)

## 依赖分析
- 第三方依赖
  - Lodash-es：提供丰富的工具函数（如 pick、get、isXxx、toUpper 等），贯穿工具库各模块。
  - Axios：HTTP 客户端，默认注入到全局属性中供请求封装使用。
  - Dayjs：日期时间处理，默认注入到全局属性中。
  - Qs：查询字符串解析，用于从 URL 查询参数中提取 token。
  - Vue：运行时 API（如 createVNode、resolveComponent、createTextVNode）用于渲染函数的动态执行。
- 内部耦合
  - 插件入口负责统一注入全局属性与注册组件/指令。
  - 工具模块之间低耦合，通过 Lodash 统一抽象类型判断与数据处理。

```mermaid
graph LR
L["lodash-es"] --> U["libs/util.js"]
L --> R["libs/request.js"]
A["axios"] --> R
D["dayjs"] --> P["packages/index.js"]
Q["qs"] --> R
V["vue runtime APIs"] --> U
P --> U
P --> R
```

**图表来源**
- [packages/index.js:14-15](file://packages/index.js#L14-L15)
- [packages/libs/util.js:1-2](file://packages/libs/util.js#L1-L2)
- [packages/libs/request.js:1-4](file://packages/libs/request.js#L1-L4)

**章节来源**
- [packages/index.js:4-19](file://packages/index.js#L4-L19)
- [packages/libs/util.js:1-2](file://packages/libs/util.js#L1-L2)
- [packages/libs/request.js:1-4](file://packages/libs/request.js#L1-L4)

## 性能考虑
- 模板替换与序列化
  - 模板替换仅在需要时进行，避免对大文本重复扫描。
  - 序列化/反序列化涉及字符串拼接与函数构造，建议仅在必要时调用，避免频繁触发。
- 请求封装
  - 参数抽取与 URL 占位替换为轻量操作，注意 keys 过多导致的 pick 开销。
  - 头注入从查询参数解析 token，建议在路由层统一管理 token，减少重复解析。
- 类型判断与转换
  - HTML 标签检测为常量集合查找，开销极低。
  - 字符串到函数转换会构造函数，建议缓存已知表达式或复用函数实例。
- 全局注入
  - 插件安装时一次性注入全局属性，避免在组件内重复创建实例。

[本节为通用性能建议，无需特定文件引用]

## 故障排查指南
- 模板替换报错
  - 现象：非法变量名导致抛出异常。
  - 排查：确认模板中的占位符变量名符合标识符规范，避免空变量名与非法字符。
  - 参考路径：[packages/libs/util.js:11-13](file://packages/libs/util.js#L11-L13)
- 序列化/反序列化异常
  - 现象：函数或 undefined 在序列化后无法正确还原。
  - 排查：确保序列化时将函数与 undefined 正确转换为字符串；反序列化时提供渲染上下文以支持函数执行。
  - 参考路径：[packages/libs/util.js:22-54](file://packages/libs/util.js#L22-L54)
- 请求失败或参数缺失
  - 现象：URL 未替换、参数未抽取、Token 未注入。
  - 排查：确认 request 为字符串或对象；检查 keys 是否正确；确认查询参数中存在 token。
  - 参考路径：[packages/libs/request.js:23-38](file://packages/libs/request.js#L23-L38), [packages/libs/request.js:39-78](file://packages/libs/request.js#L39-L78)
- 全局属性未生效
  - 现象：组件内无法访问 $http、$dayjs、$_ 等。
  - 排查：确认已在应用入口安装插件；检查插件安装顺序与全局属性注入逻辑。
  - 参考路径：[packages/index.js:13-19](file://packages/index.js#L13-L19), [src/main.js:7](file://src/main.js#L7)

**章节来源**
- [packages/libs/util.js:11-13](file://packages/libs/util.js#L11-L13)
- [packages/libs/util.js:22-54](file://packages/libs/util.js#L22-L54)
- [packages/libs/request.js:23-38](file://packages/libs/request.js#L23-L38)
- [packages/libs/request.js:39-78](file://packages/libs/request.js#L39-L78)
- [packages/index.js:13-19](file://packages/index.js#L13-L19)
- [src/main.js:7](file://src/main.js#L7)

## 结论
该工具函数库通过 Lodash-es 的深度集成与插件化的全局注入，提供了稳定的数据处理、类型判断、字符串处理与请求封装能力。其设计强调：
- 易用性：统一的 API 与灵活的调用形态
- 可靠性：完善的错误处理与类型校验
- 可扩展性：清晰的模块边界与独立实现（libs 与 core/src/libs）

建议在实际项目中遵循“按需使用、避免过度序列化/反序列化、统一管理全局属性”的原则，以获得更好的性能与可维护性。

[本节为总结性内容，无需特定文件引用]

## 附录

### 分类索引与使用示例指引
- 字符串模板与序列化
  - 示例路径：[packages/libs/util.js:4-19](file://packages/libs/util.js#L4-L19), [packages/libs/util.js:22-54](file://packages/libs/util.js#L22-L54)
- 请求封装与 URL 占位替换
  - 示例路径：[packages/libs/request.js:39-78](file://packages/libs/request.js#L39-L78)
- 类型判断与转换
  - 示例路径：[packages/libs/util.js:80-110](file://packages/libs/util.js#L80-L110)
- 国际化字符串格式化
  - 示例路径：[packages/core/src/locale/format.js:23-46](file://packages/core/src/locale/format.js#L23-L46)

### 在组件中的使用方式与最佳实践
- 全局属性访问
  - 通过全局属性访问 HTTP 客户端、日期库与 Lodash 实例，避免在组件内重复导入。
  - 参考路径：[packages/index.js:13-19](file://packages/index.js#L13-L19)
- 插件安装
  - 在应用入口安装插件，确保全局属性与组件注册生效。
  - 参考路径：[src/main.js:7](file://src/main.js#L7)
- 最佳实践
  - 将模板替换与序列化限制在必要的场景，避免频繁触发。
  - 对请求封装统一管理 headers 与 keys，减少重复逻辑。
  - 对字符串到函数的转换进行缓存或复用，降低函数构造成本。

**章节来源**
- [packages/index.js:13-19](file://packages/index.js#L13-L19)
- [src/main.js:7](file://src/main.js#L7)