# @imhjh/common 文档

[源码](https://gitee.com/hjh925678208/common)

## 安装

```bash
# npm
npm install @imhjh/common --save-dev
# yarn
yarn add @imhjh/common --save
```

## 方法库

通过 `import from` 导入.

```js
// 使用 dataType 方法
import { dataType } from "@imhjh/common"
```

### dataType

数据类型判断方法.

通过 `type`、`instanceof` 判断数据类型.

可判断 布尔值、字符串、数字、数组、函数、file、blob、json 对象、时间对象、undefined、null.

无法判断的类型返回 `false`.

```ts
type DataType = "boolean" | "string" | "number" | "array" | "function" | "date" | "file" | "blob" | "object" | "undefined" | "null" | false
function dataType(v: any): DataType
```

```js
// 获取 "字符串" 的类型

const type = dataType("字符串")

console.log(type) // "string"
```

基于 `dataType` 衍生出以下函数, 对值类型进行是否判断, 返回 boolean.

```ts
type func = (data:any): boolean

isString(data) // 是否为 String

isNumber(data) // 是否为 Number

isBoolean(data) // 是否为 Boolean

isFile(data) // 是否为 File

isBlob(data) // 是否为 Blob

isArray(data) // 是否为 Array

isFunction(data) // 是否为 Function

isDate(data) // 是否为 Date

isObject(data) // 是否为 Object

isUndefined(data) // 是否为 undefined

isNull(data) // 是否为 null
```

### useDebounce

对传入的函数进行封装, 返回一个防抖函数.

默认防抖延迟 0ms, 但内部使用 `setTimeout`, 因此实际延迟受**浏览器最小延迟**与**执行栈执行时间影响**.

```ts
function useDebounce(fn: Function, delay: number = 0): Function
```

```js
const searchAjax = () => {
  fetch("/search?str=")
}

const search = useDebounce(searchAjax, 2000)

// search 是一个延迟 2s 执行的防抖函数, 2s 内重复触发只执行最后一次触发.
```

### useThrottle

对传入的函数进行封装, 返回一个节流函数.

内部使用 `async / await` 关键字, 当传入函数**执行完毕**后一个流程才算结束.

```ts
function useThrottle(fn: Function, delay?: number): Function
```

不设限制延迟.

函数执行完毕后就可以重新触发.

```js
const getListAjax = async () => {
  await fetch("/getList") // 假设需要 3s
}
// getList 执行后, 3s 后才能重新触发.
const getList = useThrottle(getListAjax, 2000)
```

设置固定延迟.

内部使用计时器, 函数执行完毕后, 等待`setTimeout`结束才能重新触发.

```js
const getListAjax = async () => {
  await fetch("/getList") // 假设需要 3s
}
// getList 触发后, 3s + 2s 后才能再触发.
const getList = useThrottle(getListAjax, 2000)
```

### deepClone

通过递归对数据进行深度克隆.

```ts
function deepClone<Type>(data: Type): Type
```

```js
const arr = [1, 2, 3]
const data = { test: 1, arr: arr }
const newData = deepClone(data)

console.log(newData) // { test: 1, arr: [1, 2, 3] }
data === newData // false
data.arr === data.arr // false
```

### uniqueArr

使用 `new Array`、`new Set` 进行数组去重.

非数组则会返回原值.

```ts
function uniqueArray<Type>(arr: Type[]): Type[]
```

```js
const arr = [1, 1, 3, 4, 1]

const newArr = uniqueArr(arr)

console.log(newArr) // [1, 3, 4]
```

### treeToList

树结构转列表.

会在每项数据内插入一个值为父级 id 的键值对（键名默认 `parent`）.

传参不是树或树组成的列表, 返回 `false`.

```ts
// 转换配置
interface TransformConfig {
  key: string
  parent: string
  children: string
  handler: <Type>(item: Type) => void
}

// 输出结果
type TransformResult = { value: object[]; pointers: object } | boolean

function treeToList(tree: any[] | object, config?: TransformConfig): TransformResult
```

```js
// 树结构, 可以使用多个树结构组成的列表
const tree = {
  id: 1,
  children: [{ id: 2 }, { id: 3 }]
}

// 转换配置 // 以下为默认值
const transformConfig = {
  id: "id", // 唯一标识的字段名
  children: "children", // 子级的字段名
  parent: "parent", // 设置父级 id 的字段名
  handler: (item) => {} // 对每项数据进行二次加工的处理器
}

const { value, pointers } = treeToList(tree, transformConfig)

value
/* 转换后的列表
  [
    { id: 1, children: [<id: 2对象>, <id:3 对象>] },
    { id: 2, parent: 1 },
    { id: 3, parent: 1 }
  ]
*/

pointers
/* 使用唯一标识 id 作为 key 的 json 对象
  {
    "1": { id: 1, children: [] },
    "2": { id: 2, parent: 1 },
    "3": { id: 3, parent: 1 }
  }
*/
```

### listToTree

列表转树结构.

传参不是列表返回 `false`.

```ts
// 转换配置
interface TransformConfig {
  key: string
  parent: string
  children: string
  handler: <Type>(item: Type) => void
}

// 输出结果
type TransformResult = { value: object[]; pointers: object } | boolean

function listToTree(list: any[], config?: TransformConfig): TransformResult
```

```js
const list = [{ id: 1 }, { id: 2, parent: 1 }, { id: 3, parent: 1 }, { id: 4 }]

// 转换配置 // 以下为默认值
const transformConfig = {
  id: "id", // 唯一标识的字段名
  parent: "parent", // 指向父级唯一标识的字段名
  children: "children", // 设置子级的字段名
  handler: (item) => {} // 对每项数据进行二次加工的处理器
}

const { value, pointers } = listToTree(list, transformConfig)

value
/* 转换后的列表
  [
    { 
      id: 1, 
      children: [ { id: 2, parent: 1 }, { id: 3, parent: 1 } ]
    },
    { id: 4 }
  ]
*/

pointers
/* 使用唯一标识 id 作为 key 的 json 对象
  {
    "1": { id: 1, children: [<对象2>, <对象3>] },
    "2": { id: 2, parent: 1 },
    "3": { id: 3, parent: 1 }
    "4": { id: 4 }
  }
*/
```

### useDate

时间解析工具.

将传入的时间参数按照指定的 format 格式进行解析.

|  格式  | 含义                | 格式 | 含义                  |
| :----: | :------------------ | :--: | :-------------------- |
| `YYYY` | 年                  |      |                       |
|  `MM`  | 月, 补 0            | `M`  | 月, 不补 0            |
|  `DD`  | 日, 补 0            | `D`  | 日, 不补 0            |
|  `HH`  | 时, 补 0, 24 小时制 | `H`  | 时, 不补 0, 24 小时制 |
|  `ss`  | 分, 补 0            | `s`  | 分, 不补 0            |
|  `mm`  | 秒, 补 0            | `m`  | 秒, 不补 0            |
|  `WW`  | 第几周, 补 0        | `W`  | 第几周, 不补 0        |

**`WW`、`W` 表示的是一个时间范围, 因此必须且只能与 `YYYY` 一起使用.**

```ts
type TimeType = Date | number | string
type ConvertedData = {
  time: TimeType
  format: string
}
interface DateItem {
  $Y: number // 年
  $M: number // 月
  $D: number // 日
  $H: number // 时
  $m: number // 分
  $s: number // 秒
  $W: number // 周
  timestamp: number // 毫秒数
  date: Date // 时间对象
}
type ParseResult = DateItem | DateItem[] | false
export function useDate(arg1?: ConvertedData): ParseResult
export function useDate(arg1?: TimeType, arg2?: string): ParseResult
export function useDate(arg1?: ConvertedData | TimeType, arg2?: string): ParseResult
```

默认参数 `new Date()`、`"YYYY-MM-DD HH:mm:ss"`.

```js
// 假设当前时间为 2022-01-01 00:00:00

useDate()
// 相当于
useDate(new Date(), "YYYY-MM-DD HH:mm:ss")
// 相当于
useDate({ time: new Date(), format: "YYYY-MM-DD HH:mm:ss" })

/* 输出结果为
  {
    $Y: 2022
    $M: 0
    $D: 10
    $H: 0
    $m: 0
    $s: 0
    $W: 1
    timestamp: 1641744000000
    date: new Date(2022, 0, 10, 0, 0, 0)
    format: "2022-1-10 00:00:00" // 基于 format 拼接的字符串
  }
*/
```

使用 Date 对象进行解析.

```js
const date = new Date(1641744000000)

useDate(date, "YYYY-MM-DD")
```

使用毫秒数进行解析.

```js
useDate(1641744000000, "YYYY-MM-DD")
```

使用字符串配合格式化字符串进行解析.

字符串格式下, time 与 format 不匹配时返回 false

```js
// 未配置解析的时间使用以下默认值
// YYYY、MM、DD 当前时间
// HH、mm、ss、ms 都是 0
useDate("2022-01-10", "YYYY-MM-DD")

// 解析错误返回 false
useDate("2022-10-10", "YYYY-MM") // false
```

对`周的字符串`解析只能实现解析出第几周, 因此只能用 `YYYY` 与 `MM`(`M`) 配合使用, 不能配合其他格式.

```js
// 以当年 `第一个周一` 开始为 `第一周`
const [start, end] = useDate("2022 第 10 周", "YYYY 第 WW 周")

// start: 指向 2022-03-07 00:00:00 的 DateItem
// end: 指向 2022-03-13 23:59:59 的 DateItem
```

### BlobToFile

Blob 转 File

```ts
// 参考 File 构造函数
function BlobToFile(
  blob: Blob, // blob 对象
  name: string, // 文件名
  options?: { type?: string; lastModified?: number }
): File
```

### FileToBlob

File 转 Blob

```ts
// 参考 Blob 构造函数
function FileToBlob(
  file: File, // 文件对象
  options?: { type?: string; endings: "transparent" | "native" }
): Blob
```

### BlobToBase64

Blob 转 base64

```ts
function BlobToBase64(blob: Blob): Promise<string>
```

### Base64ToBlob

base64 转 Blob

```ts
function Base64ToBlob(base64: string): Blob
```

### FileToBase64

File 转 base64

```ts
function FileToBase64(file: File): Promise<string>
```

### Base64ToFile

base64 转 File

```ts
function Base64ToFile(base64: string, name: string): File
```

### copyText

将文本复制到剪切板

```ts
function copyText(text: string): Promise<void>
```

## 样式库

```js
// PC端引入
import "@imhjh/common/css/index.css"

// 移动端引入：去除移动端不适配的样式
import "@imhjh/common/css/index.mobile.css"
```

### 弹性布局相关

示例 `.父级(--子级){0,3}`.

可配合 0-3 个子级, 按 `align-items`、`justify-content`、`flex-warp` 的顺序拼接.

#### 容器样式

- 父级

  | 名称       | 对应属性                                |
  | :--------- | :-------------------------------------- |
  | `flex`     | `display: flex`                         |
  | `flex-col` | `display: flex; flex-direction:column;` |

- `align-items` 子级

  | 名称  | 对应属性                   |
  | :---- | :------------------------- |
  | `a-s` | `align-items: flex-start;` |
  | `a-c` | `align-items: center;`     |
  | `a-e` | `align-items: flex-end;`   |
  | `a-b` | `align-items: baseline;`   |

- `justify-content` 子级

  | 名称   | 对应属性                          |
  | :----- | :-------------------------------- |
  | `j-s`  | `justify-content: flex-start;`    |
  | `j-c`  | `justify-content: center;`        |
  | `j-e`  | `justify-content: flex-end;`      |
  | `j-sb` | `justify-content: space-between;` |
  | `j-sa` | `justify-content: space-around;`  |
  | `j-se` | `justify-content: space-evenly;`  |

- `flex-grow` 子级

  | 名称   | 对应属性           |
  | :----- | :----------------- |
  | `wrap` | `flex-wrap: wrap;` |

部分类名对应的属性

```css
.flex {
  display: flex;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

.flex-col--wrap {
  display: flex;
  flex-direction: column;

  flex-wrap: wrap;
}

.flex-col--a-c--wrap {
  display: flex;
  flex-direction: column;

  align-items: center;

  flex-wrap: wrap;
}

.flex-col--a-c--j-c--wrap {
  display: flex;
  flex-direction: column;

  align-items: center;

  justify-content: center;

  flex-wrap: wrap;
}
```

#### 项目样式

- `flex-grow`

  `.grow-0` ~ `.grow-10` 对应 `flex-grow: 0;` ~ `flex-grow: 10;`

- `flex-shrink`

  `.shrink-0` ~ `.shrink-10` 对应 `flex-shrink: 0;` ~ `flex-shrink: 10;`

### 尺寸样式

`.w-0p` ~ `.w-1000p` 对应 `width: 0;` ~ `width: 1000px;`

`.h-0p` ~ `.h-1000p` 对应 `height: 0;` ~ `height: 1000px;`

`.w-0pct` ~ `.w-100pct` 对应 `width: 0%;` ~ `width: 100%;`

`.h-0pct` ~ `.h-100pct` 对应 `height: 0%;` ~ `height: 100%;`

### 文本省略

`.elli-1` ~ `.elli-10`: 仅保留 `1-10`, 其余行省略.

`.elli-1-hover` ~ `.elli-10-hover`: 移入时取消省略.
