npm package: @herongxhr/network-status
Description: A Vue 3 composable and component for monitoring network status.
Author: ronnie
Latest version: 0.0.4

# @herongxhr/network-status

![NPM Version](https://img.shields.io/npm/v/@herongxhr/network-status.svg)
![NPM Downloads](https://img.shields.io/npm/dm/@herongxhr/network-status.svg)
![License](https://img.shields.io/npm/l/@herongxhr/network-status.svg)
![Build Status](https://img.shields.io/github/actions/workflow/status/xai/@herongxhr/network-status/ci.yml)

一个轻量级的 Vue 3 可组合函数和可选模板，用于实时监控网络状态。本包提供了一个灵活的 `useNetworkStatus` 可组合函数来管理网络检测和信号强度，以及一个基于 Tailwind CSS 样式的可定制 `NetworkStatusTemplate` 组件，方便快速集成。

## 特性

- **实时网络检测**：使用 `fetch` 请求监控网络状态，支持自定义检测间隔。
- **信号强度可视化**：根据延迟阈值显示 0-4 条信号条。
- **可定制警报**：支持离线、弱信号或无信号的自定义警报消息，3 秒自动关闭。
- **延迟格式化**：支持自定义延迟显示的小数位数（例如 `123.4` 毫秒）。
- **定位灵活**：支持多种警报位置（`top-right`、`bottom-left`、`center` 等）。
- **无头设计**：可自由使用可组合函数构建自定义 UI，或使用提供的 Tailwind 模板。
- **TypeScript 支持**：提供完整的类型定义，集成无缝。

## 安装

通过 npm 安装：

```bash
npm install @herongxhr/network-status
```

### 依赖要求

需要 **Vue 3**：

```bash
npm install vue@3
```

## 使用方法

### 1. 使用 `useNetworkStatus` 可组合函数

`useNetworkStatus` 提供网络状态、延迟和警报的响应式状态，可集成到任何 Vue 3 组件中，搭配自定义 UI。

#### 示例：使用普通 CSS 的自定义 UI

```vue
<template>
  <div class="network-container">
    <div class="signal-bars">
      <div
        v-for="(active, index) in signalBars"
        :key="index"
        :class="['bar', active ? signalClass : 'bg-gray-300']"
        :style="{ height: `${(index + 1) * 4}px` }"
      ></div>
    </div>
    <span class="status-text">{{ statusText }}</span>
    <span class="latency">{{ formattedLatency }} ms</span>
    <div
      v-if="showAlert"
      class="alert"
      :style="getPositionStyle(alertPosition)"
    >
      {{ alertMessage }}
      <button class="close-btn" @click="closeAlert">×</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useNetworkStatus } from "@herongxhr/network-status";

const {
  networkStatus,
  formattedLatency,
  signalBars,
  statusText,
  showAlert,
  alertMessage,
  closeAlert,
  alertPosition,
} = useNetworkStatus({
  checkUrl: "https://your-api-endpoint.com/health",
  statusTexts: ["无信号", "信号很差", "信号较弱", "信号良好", "信号优秀"],
  alertMessages: ["离线了！", "信号丢失！", "信号很弱！"],
  checkInterval: 3000,
  decimalPlaces: 1,
});

const signalClass = computed(() => {
  const status = networkStatus.value;
  if (status === 0) return "bg-gray-500";
  if (status <= 1) return "bg-red-500";
  if (status === 2) return "bg-yellow-500";
  if (status === 3) return "bg-green-500";
  return "bg-green-700";
});

const getPositionStyle = (position: string) => {
  const [vertical, horizontal] = position.split("-");
  const style: { [key: string]: string } = {};
  if (vertical === "top") style.top = "1rem";
  else if (vertical === "bottom") style.bottom = "1rem";
  if (horizontal === "left") style.left = "1rem";
  else if (horizontal === "right") style.right = "1rem";
  else if (horizontal === "center") {
    style.left = "50%";
    style.transform = "translateX(-50%)";
  }
  return style;
};
</script>

<style scoped>
.network-container {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 4px;
}
.signal-bars {
  display: flex;
  gap: 2px;
}
.bar {
  width: 4px;
  transition: all 0.3s ease;
}
.status-text {
  font-size: 12px;
  color: #2d3748;
}
.latency {
  font-size: 12px;
  color: #4a5568;
}
.alert {
  position: fixed;
  padding: 8px 12px;
  background: #fef2f2;
  color: #741a1a;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.close-btn {
  margin-left: 8px;
  border: none;
  background: none;
  color: #741a1a;
  cursor: pointer;
}
</style>
```

#### 注意事项

- **自定义 `checkUrl`**：提供可靠的健康检查端点以确保延迟检测准确。默认使用当前主机根路径 (`/`) 并附带警告。
- **延迟格式化**：使用 `decimalPlaces` 控制 `formattedLatency` 的精度（例如，`1` 表示 `123.4` 毫秒）。

### 2. 使用 `NetworkStatusTemplate` 组件

`NetworkStatusTemplate` 组件提供基于 Tailwind CSS 的预构建 UI。

#### 示例：使用 Tailwind CSS 的模板

```vue
<template>
  <NetworkStatusTemplate
    position="bottom-right"
    position-offset="1.5rem"
    container-class="shadow-md bg-white dark:bg-gray-800"
    alert-class="bg-red-100 text-red-800"
    :status-texts="['无信号', '信号很差', '信号较弱', '信号良好', '信号优秀']"
    :alert-messages="['离线了！', '信号丢失！', '信号很弱！']"
    check-url="https://your-api-endpoint.com/health"
    check-interval="5000"
    decimal-places="2"
  />
</template>

<script setup lang="ts">
import { NetworkStatusTemplate } from "@herongxhr/network-status";
</script>
```

#### 属性

| 属性                       | 类型       | 默认值                        | 描述                         |
| -------------------------- | ---------- | ----------------------------- | ---------------------------- |
| `position`                 | `string`   | `"top-right"`                 | 组件位置（`top-right` 等）。 |
| `positionOffset`           | `string`   | `"1rem"`                      | 定位偏移量（例如 `1rem`）。  |
| `containerClass`           | `string`   | `"h-4 flex ..."`              | 主容器的 Tailwind 类。       |
| `signalBarsContainerClass` | `string`   | `"h-full py-[2px] ..."`       | 信号条容器的类。             |
| `signalBarClass`           | `string`   | `"transition-all ..."`        | 单个信号条的类。             |
| `statusTextContainerClass` | `string`   | `"flex flex-col"`             | 状态文本容器的类。           |
| `statusTextClass`          | `string`   | `"h-full flex ..."`           | 状态文本的类。               |
| `latencyTextClass`         | `string`   | `"text-xs text-gray-600 ..."` | 延迟文本的类。               |
| `alertClass`               | `string`   | `"p-2 rounded"`               | 警报框的类。                 |
| `alertMessageClass`        | `string`   | `""`                          | 警报消息的类。               |
| `closeButtonClass`         | `string`   | `"absolute top-1 ..."`        | 关闭按钮的类。               |
| `statusTexts`              | `string[]` | `["无信号", ...]`             | 5 个状态文本的数组。         |
| `alertMessages`            | `string[]` | `["离线了！", ...]`           | 3 个警报消息的数组。         |
| `checkUrl`                 | `string`   | 当前主机                      | 网络检测的 URL。             |
| `checkInterval`            | `number`   | `5000`                        | 网络检测间隔（毫秒）。       |
| `decimalPlaces`            | `number`   | `0`                           | 延迟显示的小数位数。         |

#### 样式属性

所有样式属性（例如 `containerStyle`、`signalBarStyle`）接受 `CSSProperties` 以进行内联 CSS 自定义。

## API 参考

### `useNetworkStatus(options?: NetworkStatusOptions)`

#### 选项

| 属性            | 类型       | 默认值              | 描述                                        |
| --------------- | ---------- | ------------------- | ------------------------------------------- |
| `initialStatus` | `number`   | `0`                 | 初始网络状态（0-4）。                       |
| `checkUrl`      | `string`   | 当前主机 (`/`)      | 网络检测的 URL。                            |
| `alertPosition` | `string`   | `"bottom-right"`    | 警报框位置（`top-right` 等）。              |
| `statusTexts`   | `string[]` | `["无信号", ...]`   | 5 个状态文本的数组。                        |
| `alertMessages` | `string[]` | `["离线了！", ...]` | 3 个警报消息的数组 [离线, 状态 0, 状态 1]。 |
| `checkInterval` | `number`   | `8000`              | 网络检测间隔（毫秒）。                      |
| `decimalPlaces` | `number`   | `0`                 | 延迟显示的小数位数。                        |

#### 返回值

| 属性                 | 类型                     | 描述                               |
| -------------------- | ------------------------ | ---------------------------------- |
| `networkStatus`      | `Ref<number>`            | 当前网络状态（0-4）。              |
| `latency`            | `Ref<number>`            | 原始延迟值（毫秒）。               |
| `formattedLatency`   | `ComputedRef<string>`    | 格式化的延迟值，带指定小数位。     |
| `signalBars`         | `ComputedRef<boolean[]>` | 4 个布尔值的数组，表示信号条状态。 |
| `statusText`         | `ComputedRef<string>`    | 当前状态文本。                     |
| `showAlert`          | `Ref<boolean>`           | 是否显示警报。                     |
| `alertMessage`       | `ComputedRef<string>`    | 当前警报消息。                     |
| `checkNetworkStatus` | `() => Promise<void>`    | 手动检查网络状态。                 |
| `closeAlert`         | `() => void`             | 手动关闭警报。                     |
| `alertPosition`      | `string`                 | 警报框位置。                       |

## 贡献

欢迎贡献！请按照以下步骤操作：

1. Fork 仓库。
2. 创建特性分支：`git checkout -b feature/new-feature`
3. 提交更改：`git commit -m 'Add new feature'`
4. 推送分支：`git push origin feature/new-feature`
5. 提交 Pull Request。

### 开发设置

- 克隆仓库：`git clone https://github.com/xai/@herongxhr/network-status.git`
- 安装依赖：`npm install`
- 运行测试：`npm run test`
- 构建包：`npm run build`

## 许可证

[MIT 许可证](LICENSE)