Skip to content

UseEventSource

功能描述

UseEventSource 是一个用于处理 Server-Sent Events (SSE) 的 Vue 组合式函数,提供了完整的 SSE 连接管理、自动重连、消息解析和事件处理能力。它基于浏览器的原生 EventSource API,为 Vue 应用提供了更加便捷和响应式的 SSE 集成方案。

安装

bash
# 使用 pnpm
pnpm add @oiij/use

# 使用 npm
npm install @oiij/use

# 使用 yarn
yarn add @oiij/use

依赖

  • vue: ^3.0.0
  • @vueuse/core: ^10.0.0

基本使用

loading

API

useEventSource(url?, options?)

创建 SSE 连接。

参数

参数类型说明
urlMaybeRefOrGetter<string | URL>SSE 连接地址
optionsUseEventSourceOptions配置选项

UseEventSourceOptions

选项类型默认值说明
manualbooleanfalse是否手动连接
autoRetryboolean | AutoRetry-自动重试配置
parseMessageboolean | functionfalse消息解析配置
handlerKeystring'type'消息处理器键名
withCredentialsbooleanfalse是否携带凭据

返回值

属性类型说明
sourceShallowRef<EventSource | null>EventSource 实例
urlRef<string | URL | undefined>连接地址
statusRef<State>连接状态
dataRef<any>最新消息数据
dataRecordRef<any[]>消息记录
errorRef<Event | null>错误信息
connect(url?, options?)Function连接 SSE
close()Function关闭连接
destroy()Function销毁连接
registerHandler(type, handler)Function注册消息处理器
onOpen(callback)Function连接打开事件
onMessage(callback)Function消息接收事件
onError(callback)Function错误事件

类型定义

ts
export type State = 'CONNECTING' | 'OPEN' | 'CLOSED'

export type AutoRetry = boolean | {
  retries?: number
  delay?: number
  onFailed?: () => void
}

export type UseEventSourceOptions<T extends HandlerType = HandlerType> = EventSourceInit & {
  manual?: boolean
  autoRetry?: AutoRetry
  parseMessage?: boolean | ((raw: any) => Record<keyof T, unknown> | Promise<Record<keyof T, unknown>>)
  handlerKey?: string
}

export type UseEventSourceReturns = {
  source: ShallowRef<EventSource | null>
  url: Ref<string | URL | undefined>
  status: Ref<State>
  data: Ref<any>
  dataRecord: Ref<any[]>
  error: Ref<Event | null>
  connect: (url?: string | URL, options?: EventSourceInit) => void
  close: () => void
  destroy: () => void
  registerHandler: <K>(type: K, handler: (data: any) => void) => () => void
  onOpen: (callback: (event: Event) => void) => void
  onMessage: (callback: (event: MessageEvent) => void) => void
  onError: (callback: (event: Event) => void) => void
}

export declare function useEventSource<T, D>(url?: MaybeRefOrGetter<string | URL>, options?: UseEventSourceOptions<T>): UseEventSourceReturns

使用示例

基础用法

vue
<script setup>
import { useEventSource } from '@oiij/use'

const { status, data, onMessage } = useEventSource('/api/events')

onMessage((event) => {
  console.log('收到消息:', event.data)
})
</script>

<template>
  <p>状态: {{ status }}</p>
  <p>数据: {{ data }}</p>
</template>

自动重试

ts
import { useEventSource } from '@oiij/use'

const { status } = useEventSource('/api/events', {
  autoRetry: {
    retries: 3,
    delay: 1000,
    onFailed: () => {
      console.log('连接失败')
    }
  }
})

消息处理器

ts
import { useEventSource } from '@oiij/use'

type EventTypes = {
  message: { content: string }
  notification: { title: string, body: string }
}

const { registerHandler } = useEventSource<EventTypes>('/api/events', {
  parseMessage: true
})

registerHandler('message', (data) => {
  console.log('消息:', data.content)
})

registerHandler('notification', (data) => {
  console.log('通知:', data.title, data.body)
})

手动连接

ts
import { useEventSource } from '@oiij/use'

const { status, connect, close } = useEventSource('/api/events', {
  manual: true
})

function handleConnect() {
  connect()
}

function handleClose() {
  close()
}