You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Nitro API流式数据传入Pinia Store并在Nuxt组件中使用?

问题原因

服务器端的Pinia Store实例和客户端的是完全独立的两个实例,你在Nitro服务器里更新的是服务器内存中的Store数据,客户端的Store根本接收不到这个更新,所以浏览器里看不到变化。

解决方案

1. 修改Nitro API,通过SSE推送流式数据

把原来直接操作Pinia的逻辑改成向客户端发送SSE事件:

export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig()
  const body = await readBody(event)

  // 设置SSE响应头
  event.res.setHeader('Content-Type', 'text/event-stream')
  event.res.setHeader('Cache-Control', 'no-cache')
  event.res.setHeader('Connection', 'keep-alive')

  const stream = await openai.beta.threads.createAndRunStream({
    assistant_id: '你的ID',
    thread: {
      messages: [
        { role: 'user', content: body.prompt || "Explain deep learning to a 5 year old." }
      ]
    }
  })

  stream
    .on('textDelta', async (textDelta, snapshot) => {
      // 向客户端发送SSE事件
      event.res.write(`data: ${JSON.stringify({ type: 'textDelta', data: snapshot })}\n\n`)
    })
    .on('toolCallDelta', async (toolCallDelta, snapshot) => {
      if (toolCallDelta.type === 'code_interpreter') {
        let output = ''
        if (toolCallDelta.code_interpreter.input) {
          output += toolCallDelta.code_interpreter.input
        }
        if (toolCallDelta.code_interpreter.outputs) {
          output += '\noutput >\n'
          toolCallDelta.code_interpreter.outputs.forEach((outputItem) => {
            if (outputItem.type === 'logs') {
              output += `\n${outputItem.logs}\n`
            }
          })
        }
        // 发送工具调用的输出
        event.res.write(`data: ${JSON.stringify({ type: 'toolCallDelta', data: output })}\n\n`)
      }
    })
    .on('textDone', async () => {
      // 发送结束信号
      event.res.write(`data: ${JSON.stringify({ type: 'done' })}\n\n`)
      event.res.end()
    })
    .on('error', (err) => {
      console.error('Stream error:', err)
      event.res.write(`data: ${JSON.stringify({ type: 'error', data: err.message })}\n\n`)
      event.res.end()
    })

  // 防止请求被提前关闭
  event.on('close', () => {
    stream.abort()
  })

  return new Promise(() => {}) // 保持连接打开
})

2. 客户端监听SSE并更新Pinia Store

在Pinia Store里添加SSE监听逻辑:

// 在Pinia Store里添加方法
export const useChatStore = defineStore('chat', () => {
  const streamOutput = ref({ value: "", annotations: [] })

  const setStreamOutput = (output) => {
    console.log("setStreamOutput", output)
    streamOutput.value = output
  }

  // 新增:发起SSE请求并监听
  const fetchStreamData = async (prompt) => {
    const eventSource = new EventSource(`/api/your-stream-endpoint?prompt=${encodeURIComponent(prompt)}`)

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data)
      switch (data.type) {
        case 'textDelta':
          setStreamOutput(data.data)
          break
        case 'toolCallDelta':
          // 这里根据需求合并数据
          setStreamOutput({
            ...streamOutput.value,
            value: streamOutput.value.value + data.data
          })
          break
        case 'done':
          eventSource.close()
          break
        case 'error':
          console.error('Stream error:', data.data)
          eventSource.close()
          break
      }
    }

    eventSource.onerror = (err) => {
      console.error('SSE error:', err)
      eventSource.close()
    }

    return eventSource
  }

  return { streamOutput, setStreamOutput, fetchStreamData }
})

3. 在客户端组件中调用

<template>
  <div>{{ chatStore.streamOutput.value }}</div>
  <button @click="startStream">开始流式请求</button>
</template>

<script setup>
const chatStore = useChatStore()

const startStream = async () => {
  await chatStore.fetchStreamData("Explain deep learning to a 5 year old.")
}
</script>
关键说明
  • Nitro服务器和客户端运行在不同环境,各自维护独立的Pinia实例,服务器端的Store更新无法直接同步到客户端。
  • 使用SSE(Server-Sent Events)是处理流式响应并同步到客户端的标准方案,适合单向的服务器到客户端的数据流。
  • 如果需要双向通信,可以考虑用WebSocket,但SSE对于这种AI流式输出场景已经足够。

内容的提问来源于stack exchange,提问作者av0000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 21:05:56