npm package: @seevin/common
Description: seevin common utilities
Latest version: 0.0.6

# @seevin/common

- [官方文档](https://seevin-ui-docs.vercel.app/)
- @seevin/common 是一个现代化的 JavaScript/TypeScript 工具库，提供常用的工具函数和类，，可以在任何 JavaScript 或 TypeScript 项目中使用。提供了一系列经过测试和优化的工具函数和类，旨在简化日常开发工作。

## 特性

- **🚀 现代化**：使用最新的 JavaScript/TypeScript 特性
- **📦 轻量级**：按需引入，支持 Tree Shaking
- **🔧 实用性**：覆盖常见的开发场景和需求
- **💪 类型安全**：完整的 TypeScript 类型定义
- **🧪 可靠性**：经过充分测试，稳定可靠
- **📚 易用性**：简洁明了的 API 设计

## 安装

```bash
# npm
npm install @seevin/common

# pnpm
pnpm install @seevin/common
```

## 快速开始

### 全量导入

```ts
import * as SeevinCommon from '@seevin/common'

const { HttpClient, devWarn, devError, isNetworkUrl, generateShortUUID, generateUUID } = SeevinCommon
```

### 按需导入（推荐）

```ts
import { HttpClient, devWarn, devError, isNetworkUrl, generateShortUUID, generateUUID } from '@seevin/common'

// 创建 HTTP 客户端实例
const client = new HttpClient({
  baseURL: 'https://api.example.com'
})

// 使用 devWarn
devWarn('MyComponent', '这是一个警告信息')

// 使用 generateUUID
const uuid = generateUUID()
console.log(uuid)
```

### 类型导入

```ts
import type { BaseResponse, RequestError, HttpClientOptions, ExtendedAxiosRequestConfig } from '@seevin/common'
import type { DevWarnFn, DevErrorFn, isNetworkUrlFn, GenerateShortUUIDFn, GenerateUUIDFn } from '@seevin/common'
```

### HTTP 工具

**HttpClient** 基于 Axios 的现代化 HTTP 客户端，支持拦截器、请求取消、错误处理等功能

**EventBus** 事件总线，用于在组件之间进行通信

### 通用工具

| 工具名称              | 说明                                      |
| --------------------- | ----------------------------------------- |
| **devWarn**           | 开发环境下输出警告信息，支持 Tree-shaking |
| **devError**          | 开发环境下输出错误信息，支持 Tree-shaking |
| **generateShortUUID** | 生成简短的随机字符串                      |
| **generateUUID**      | 生成标准的 UUID 字符串                    |
| **is**                | 判断值是否为某个类型                      |
| **isFunction**        | 判断是否为函数                            |
| **isDef**             | 判断是否已定义                            |
| **isUnDef**           | 判断是否未定义                            |
| **isObject**          | 判断是否为对象                            |
| **isDate**            | 判断是否为时间                            |
| **isNumber**          | 判断是否为数值                            |
| **isAsyncFunction**   | 判断是否为 AsyncFunction                  |
| **isPromise**         | 判断是否为 promise                        |
| **isString**          | 判断是否为字符串                          |
| **isBoolean**         | 判断是否为 boolean 类型                   |
| **isArray**           | 判断是否为数组                            |
| **isClient**          | 判断是否为客户端                          |
| **isWindow**          | 判断是否为浏览器                          |
| **isElement**         | 判断是否为 element 元素                   |
| **isNull**            | 判断是否为 null                           |
| **isNullOrUnDef**     | 判断是否为 null 或 undefined              |
| **isHexColor**        | 判断是否为 16 进制颜色                    |
| **isNetworkUrl**      | 判断给定 URL 是否为网络图片               |
| **isImage**           | 判断是否为图片 URL                        |
| **isVideo**           | 判断是否为视频 URL                        |
| **isDingTalk**        | 判断是否为钉钉环境                        |
| **isAndroid**         | 判断是否为安卓设备                        |
| **isiOS**             | 判断是否为 iOS 设备                       |
| **isWeChat**          | 判断是否为微信环境                        |
| **isAlipay**          | 判断是否为支付宝环境                      |

## 使用示例

### HTTPClient 使用示例

在使项目中实例化HttpClient，如在项目src/api/index.ts中，

```ts
import { MessagePlugin } from 'tdesign-vue-next'
import { HttpClient, axios, type AxiosError } from '@seevin/common'
import { checkNetWorkStatus } from '@seevin/ui'

// 创建客户端实例
export default new HttpClient({
  baseURL: import.meta.env.PUBLIC_BASE_API,
  interceptors: {
    request: [
      {
        onFulfilled: config => {
          const token = 'your token'
          config.headers.set('Authorization', `Bearer ${token}`)
          return config
        }
      }
    ],
    response: [
      {
        onFulfilled: response => {
          const resData = response.data
          if (resData.code !== 200) {
            MessagePlugin.error(resData.msg || '服务异常，请稍后重试')
            throw response
          }
          return response
        },
        onRejected: (error: AxiosError) => {
          if (!axios.isCancel(error)) {
            // 请求超时 && 网络错误单独判断，没有 response
            if ((error as AxiosError).message.indexOf('timeout') !== -1) MessagePlugin.error('请求超时！请您稍后重试')
            if ((error as AxiosError).message.indexOf('Network Error') !== -1)
              MessagePlugin.error('网络错误！请您稍后重试')
            // 根据服务器响应的错误状态码，做不同的处理
            if ((error as AxiosError).response) checkNetWorkStatus((error as AxiosError)!.response!.status)
          }
          return Promise.reject(error)
        }
      }
    ]
  }
})
```

```ts
// 在业务模块（如user模块）的api文件中引入HttpClient实例
import http from '@/api'

export const userListAPI = (params: ReqLoginMsg) => {
  return http.get<ResUser[]>('/user/list', { params })
}
```

### 在 Vue 组件中使用

```vue
<template>
  <div>
    <TButton @click="loadData" :loading="loading">加载数据</TButton>
    <div v-if="userList.length > 0">
      <pre>{{ JSON.stringify(userList) }}</pre>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { userListAPI } from '@/api/modules/user'
import type { ResUser } from '@/api/modules/user'

const loading = ref(false)
const userList = ref<ResUser[]>([])

const loadData = async () => {
  loading.value = true
  try {
    loading.value = true
    const { data } = await userListAPI({
      page: 1,
      limit: 10
    })
    userList.value = data
  } catch (error) {
    console.error('加载失败:', error)
  } finally {
    loading.value = false
  }
}
</script>
```

## TypeScript 支持

工具库提供完整的 TypeScript 类型定义：

```ts
// 自动类型推导
const client = new HttpClient({
  baseURL: 'https://api.example.com',
  timeout: 5000 // 类型检查
})

// 泛型支持
interface ResUser {
  id: number
  name: string
  email: string
}

const users = await client.get<ResUser[]>('/users')
// users.data 具有正确的类型：ResUser[]

// 导入类型
import type { BaseResponse, RequestError, HttpClientOptions, ExtendedAxiosRequestConfig } from '@seevin/common'
```

## EventBus 使用示例

### Vue 项目基本使用

**推荐使用 `useEventBus` 进行统一的事件管理：**

```typescript
// 1. 定义事件类型 (src/types/events.ts)
interface AppEvents {
  'user:login': { userId: string; username: string }
  'user:logout': { userId: string }
  'cart:add': { productId: string; quantity: number }
  'notification:show': { message: string; type: 'success' | 'error' }
}

// 2. 创建项目级 Hook (src/hooks/useAppEventBus.ts)
import { createEventBus, useEventBus } from '@seevin/common'
import type { AppEvents } from '@/types/events'

// 创建共享实例
const appEventBus = createEventBus<AppEvents>()

// 导出使用共享实例的 Hook
export const useAppEventBus = () => useEventBus<AppEvents>(appEventBus)

// 3. 在组件中使用
// ComponentA.vue - 发送事件
const { emit } = useAppEventBus()
const handleLogin = () => {
  emit('user:login', { userId: '123', username: 'john' })
}

// ComponentB.vue - 监听事件
const { on } = useAppEventBus()
on('user:login', data => {
  console.log('用户登录:', data.username) // 完整的类型支持
})
```