Vue Academy · 课时

使用 useSubscription 实现实时订阅

配置 WebSocket 链接、useSubscription(),以及将订阅数据合并到响应式状态中

第 4 / 4 课13 个步骤

使用 useSubscription 实现实时订阅 是 CoddyKit 上的免费 Vue Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Vue Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Vue Academy 课程共包含 4 节课。

使用订阅实现实时通信

GraphQL 订阅会通过持久连接将数据从服务器推送到客户端。查询只拉取一次数据,而订阅会持续推送更新,非常适合聊天、实时信息流和通知。

WebSocket 传输

订阅需要长期保持的连接,因此使用 WebSockets 而不是 HTTP。graphql-ws 库通过 GraphQLWsLink 提供现代协议。

npm install graphql-ws

创建 WebSocket 链接

将 graphql-ws 客户端封装在 GraphQLWsLink 中,并将其指向 wss:// 订阅端点。

import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
import { createClient } from 'graphql-ws'

const wsLink = new GraphQLWsLink(createClient({
  url: 'wss://api.example.com/graphql'
}))

传输方式问题

查询和变更仍应通过 HTTP 传输,而订阅则通过 WebSocket 传输。您不能对所有内容使用同一个链接——需要根据操作类型拆分流量。

拆分链接

split 函数会为每个操作选择路由:根据解析后的操作定义,将订阅发送到 WebSocket 链接,将其他所有操作发送到 HTTP 链接。

import { split, HttpLink } from '@apollo/client/core'
import { getMainDefinition } from '@apollo/client/utilities'

const httpLink = new HttpLink({ uri: '/graphql' })

const link = split(
  ({ query }) => {
    const def = getMainDefinition(query)
    return def.kind === 'OperationDefinition' && def.operation === 'subscription'
  },
  wsLink,
  httpLink
)

将拆分链接接入客户端

将组合后的 link 传给 Apollo 客户端,而不是传入普通的 uri。现在客户端知道如何为每个操作选择路由。

const apolloClient = new ApolloClient({
  link,
  cache: new InMemoryCache()
})

useSubscription 基础

useSubscription 组合式函数会打开数据流并返回响应式状态。和 useQuery 一样,它会提供 result、loading 和 error。

import { useSubscription } from '@vue/apollo-composable'
import { gql } from '@apollo/client/core'

const { result } = useSubscription(gql(
  'subscription { messageAdded { id text } }'
))

处理每次推送

使用 onResult 钩子,在每个推送事件到达时做出响应——这里正是处理流式数据的自然位置。

const { onResult } = useSubscription(MESSAGE_ADDED)
onResult((res) => {
  console.log('New message', res.data.messageAdded)
})

推入响应式数组

一种常见模式是:维护一个本地响应式数组,并追加每个新事件,让模板渲染出一个实时增长的列表。

const messages = ref([])
const { onResult } = useSubscription(MESSAGE_ADDED)
onResult((res) => {
  messages.value.push(res.data.messageAdded)
})

订阅变量

订阅和查询一样也接受变量——例如,订阅单个聊天房间中的消息。

useSubscription(
  gql('subscription($room: ID!) { messageAdded(room: $room) { text } }'),
  { room: 'general' }
)

订阅与轮询

轮询会按计时器重新获取查询;订阅则只在发生变化时推送。对于真正的实时数据,订阅更高效;如果接近实时就足够,轮询则更简单。

快速检查

测试您对订阅的掌握程度。

回顾

您已经学习了实时订阅:

  • 订阅会通过 GraphQLWsLink(graphql-ws)使用 WebSockets 推送数据。
  • 使用 split() 将订阅通过 WS 发送,并将查询和变更通过 HTTP 发送。
  • useSubscription 会返回响应式 result,并通过 onResult 处理每次推送。
  • 将推送事件追加到响应式数组中,即可创建实时列表。
免费开始

用 AI 导师学习 HTML — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
42
课程
156

常见问题解答

「使用 useSubscription 实现实时订阅」课时是免费的吗?

是的 — 「使用 useSubscription 实现实时订阅」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Vue Academy 课程的其余内容,请升级到 CoddyKit PRO。 Vue Academy 课程共包含 4 节课。

「使用 useSubscription 实现实时订阅」这节课中我会学到什么?

配置 WebSocket 链接、useSubscription(),以及将订阅数据合并到响应式状态中 你通过在浏览器中直接运行的动手代码来练习 Vue Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Vue Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Vue Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用 useSubscription 实现实时订阅」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Vue Academy 课中编写并运行代码吗?

能。每节 Vue Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 在 Vue 3 中配置 Apollo Client
  2. 使用 useQuery 获取数据
  3. 使用 useMutation 修改数据
  4. 使用 useSubscription 实现实时订阅
← 返回 Vue Academy