跪拜 Guibai
← All articles
JavaScript · Frontend · Artificial Intelligence

Streaming AI Output in the Browser: A ReadableStream and Vue Walkthrough

By 橘子星 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

The jump from a single JSON response to a streaming response is the difference between an AI product that feels broken and one that feels alive. The technique itself is a small configuration change and a standard browser API, but it's now a baseline expectation for any chat interface.

Summary

A plain-Vue project built with Vite demonstrates how to replace the standard `response.json()` call with a streaming pipeline. The server-side DeepSeek API is told to stream tokens by adding `stream: true` to the request body. On the client, a `TextDecoder` and a `while` loop over `reader.read()` append each chunk to a reactive `ref`, which Vue's template interpolation renders immediately.

The walkthrough also lays out the Vue fundamentals that make this work: mounting an app to a single `<div>`, using Single File Components, and binding data with `{{ }}`, `v-model`, and `v-if`. The result is a typewriter effect that turns a 10-second wait into a continuous, visible stream of text.

Every piece of the data flow is traced, from the user's input through `v-model` into the fetch call, through the `ReadableStream` reader, and back into the reactive `content` variable that drives the UI.

Takeaways
Setting `stream: true` in the fetch body tells the LLM server to emit tokens as they are generated instead of batching them.
A `ReadableStream` reader paired with a `TextDecoder` consumes the response body chunk-by-chunk.
Each chunk is appended to a Vue `ref`; because the ref is reactive, the template re-renders automatically, creating a typewriter effect.
Vue's `v-model` provides two-way binding for the input field, while `{{ }}` interpolation handles one-way display of the streaming text.
The entire app mounts to a single `<div id="app">` via `createApp(App).mount('#app')`, with all logic living in a Single File Component.
Conclusions

Streaming is often framed as a complex real-time protocol, but for LLM APIs it's just an HTTP request with a flag and a standard browser stream reader.

The tutorial's value is in demystifying the pipeline: the server-side contract (`stream: true`) and the client-side mechanism (`ReadableStream`) are independent concerns that happen to pair perfectly.

By grounding the explanation in Vue's reactivity system, the walkthrough shows that the frontend framework does the heavy lifting of keeping the UI in sync; the developer only needs to push bytes into a variable.

Concepts & terms
ReadableStream
A browser API that provides a readable stream of binary data, allowing a client to consume a server response incrementally via a reader instead of waiting for the entire payload.
Vue SFC (Single File Component)
A `.vue` file that encapsulates a component's template (HTML), script (JavaScript), and style (CSS) in one file, promoting reusable, self-contained UI units.
Reactive Data (ref)
In Vue, a value wrapped with `ref()` that triggers automatic DOM updates whenever its `.value` changes, eliminating manual DOM manipulation.
v-model
A Vue directive that creates two-way data binding between a form input and a piece of state, so user input updates the data and data changes update the input.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗