一个轻量级的 Vue.js 插件,用于处理 AI 大模型的流式响应(SSE - Server-Sent Events)。支持实时接收 AI 回复内容,提供简洁的 API 和完善的错误处理。
- 🚀 流式响应处理 - 完整支持 SSE (Server-Sent Events) 协议
- 💬 实时内容更新 - 通过回调函数实时获取 AI 回复
- 🔄 请求管理 - 支持取消正在进行的请求
- 🔐 自动认证 - 自动添加 Token 到请求头
- ⚡ 轻量高效 - 零依赖,体积小巧
- 🎯 TypeScript 友好 - 提供完整的类型定义
- 🔧 高度可配置 - 灵活的配置选项
- 🛡️ 错误处理 - 完善的异常捕获机制
npm install vue-ai-stream-helperyarn add vue-ai-stream-helper<script src="https://unpkg.com/vue-ai-stream-helper"></script>// main.js
import Vue from 'vue';
import AIStreamHelper from 'vue-ai-stream-helper';
Vue.use(AIStreamHelper, {
baseURL: 'https://your-api.com',
endpoint: '/api/chat',
model: 'qwen-turbo',
getToken: () => localStorage.getItem('token'), // 获取Token的函数
headers: {
// 自定义请求头(可选)
}
});<template>
<div>
<el-button @click="callAI" :loading="loading">
{{ loading ? 'AI思考中...' : '开始对话' }}
</el-button>
<div class="response">{{ aiResponse }}</div>
</div>
</template>
<script>
export default {
data() {
return {
loading: false,
aiResponse: ''
}
},
methods: {
async callAI() {
this.loading = true;
this.aiResponse = '';
await this.$aiChat.chat({
content: '请介绍一下你自己',
// 实时接收AI回复
onMessage: ({ fullContent }) => {
this.aiResponse = fullContent;
},
// 完成回调
onComplete: (fullContent) => {
this.$message.success('回复完成!');
this.loading = false;
},
// 错误处理
onError: (error) => {
this.$message.error('调用失败');
this.loading = false;
}
});
}
}
}
</script>| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| baseURL | String | 是 | - | API 基础 URL |
| endpoint | String | 是 | - | 接口端点路径 |
| model | String | 否 | 'qwen-turbo' | 默认模型名称 |
| getToken | Function | 否 | () => '' | 获取认证 Token 的函数 |
| headers | Object | 否 | {} | 自定义请求头 |
发送流式聊天请求。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| content | String | 否* | 用户消息内容(简化版) |
| messages | Array | 否* | 完整消息列表(高级版) |
| model | String | 否 | 模型名称(覆盖默认配置) |
| onMessage | Function | 否 | 接收消息时的回调 |
| onComplete | Function | 否 | 完成时的回调 |
| onError | Function | 否 | 错误时的回调 |
*注:content 和 messages 至少提供一个
{
content: '当前片段内容',
fullContent: '累积的完整内容',
rawData: {} // 原始响应数据
}取消当前正在进行的请求。
this.$aiChat.abort();快捷方法,用于简单的一次性调用。
await this.$streamChat('你好', {
onMessage: ({ fullContent }) => console.log(fullContent)
});export default {
methods: {
async basicChat() {
await this.$aiChat.chat({
content: '什么是Vue.js?',
onMessage: ({ fullContent }) => {
console.log('当前内容:', fullContent);
},
onComplete: (fullContent) => {
console.log('完整回复:', fullContent);
}
});
}
}
}export default {
methods: {
async professionalChat() {
await this.$aiChat.chat({
messages: [
{
role: 'system',
content: '你是一个专业的前端开发工程师'
},
{
role: 'user',
content: '请解释Vue的响应式原理'
}
],
onMessage: ({ fullContent }) => {
this.response = fullContent;
}
});
}
}
}export default {
data() {
return {
history: [
{
role: 'system',
content: '你是一个helpful的助手'
}
]
}
},
methods: {
async sendMessage(userInput) {
// 添加用户消息
this.history.push({
role: 'user',
content: userInput
});
let aiReply = '';
await this.$aiChat.chat({
messages: this.history,
onMessage: ({ fullContent }) => {
aiReply = fullContent;
},
onComplete: () => {
// 添加AI回复到历史
this.history.push({
role: 'assistant',
content: aiReply
});
}
});
}
}
}<template>
<div>
<el-button @click="start">开始</el-button>
<el-button @click="stop" v-if="generating">取消</el-button>
</div>
</template>
<script>
export default {
data() {
return {
generating: false
}
},
methods: {
async start() {
this.generating = true;
await this.$aiChat.chat({
content: '写一篇很长的文章...',
onMessage: (data) => console.log(data),
onComplete: () => {
this.generating = false;
}
});
},
stop() {
this.$aiChat.abort();
this.generating = false;
}
},
beforeDestroy() {
// 组件销毁时取消请求
this.$aiChat.abort();
}
}
</script>import { createAIChat } from 'vue-ai-stream-helper';
export default {
data() {
return {
aiChat: null
}
},
created() {
this.aiChat = createAIChat({
baseURL: 'https://your-api.com',
endpoint: '/api/chat',
getToken: () => this.$store.state.token
});
},
methods: {
async chat() {
await this.aiChat.chat({
content: 'Hello',
onMessage: (data) => console.log(data)
});
}
}
}<template>
<div class="ai-resume-optimizer">
<el-input
v-model="resumeContent"
type="textarea"
:rows="8"
placeholder="请输入简历内容"
/>
<div class="actions">
<el-button
type="primary"
:loading="optimizing"
@click="optimize"
icon="el-icon-magic-stick"
>
{{ optimizing ? '优化中...' : 'AI优化' }}
</el-button>
<el-button
v-if="optimizing"
@click="cancel"
icon="el-icon-close"
>
取消
</el-button>
</div>
<div v-if="optimizedContent" class="result">
<h3>优化结果:</h3>
<div class="content">{{ optimizedContent }}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
resumeContent: '',
optimizedContent: '',
optimizing: false
}
},
methods: {
async optimize() {
if (!this.resumeContent.trim()) {
this.$message.warning('请输入简历内容');
return;
}
this.optimizing = true;
this.optimizedContent = '';
try {
await this.$aiChat.chat({
messages: [
{
role: 'system',
content: '你是一个专业的简历优化专家。请帮助用户优化简历,使其更专业、简洁、有吸引力。'
},
{
role: 'user',
content: `请优化以下简历:\n\n${this.resumeContent}`
}
],
onMessage: ({ fullContent }) => {
this.optimizedContent = fullContent;
},
onComplete: () => {
this.$message.success('优化完成!');
this.optimizing = false;
},
onError: (error) => {
this.$message.error('优化失败:' + error.message);
this.optimizing = false;
}
});
} catch (error) {
if (error.name !== 'AbortError') {
this.$message.error('请求异常');
}
this.optimizing = false;
}
},
cancel() {
this.$aiChat.abort();
this.optimizing = false;
this.$message.info('已取消优化');
}
},
beforeDestroy() {
this.$aiChat.abort();
}
}
</script>
<style scoped>
.ai-resume-optimizer {
padding: 20px;
}
.actions {
margin: 16px 0;
}
.result {
margin-top: 20px;
padding: 16px;
background: #f5f7fa;
border-radius: 4px;
}
.content {
white-space: pre-wrap;
line-height: 1.8;
}
</style>Vue.use(AIStreamHelper, {
baseURL: 'https://api.openai.com',
endpoint: '/v1/chat/completions',
model: 'gpt-3.5-turbo',
getToken: () => localStorage.getItem('openai_token')
});Vue.use(AIStreamHelper, {
baseURL: 'https://dashscope.aliyuncs.com',
endpoint: '/api/v1/services/aigc/text-generation/generation',
model: 'qwen-turbo',
getToken: () => localStorage.getItem('qwen_token')
});Vue.use(AIStreamHelper, {
baseURL: 'https://your-api.com',
endpoint: '/api/chat',
model: 'your-model',
getToken: () => store.state.token,
headers: {
'X-Custom-Header': 'value'
}
});插件期望的 SSE 响应格式:
data:{"choices":[{"delta":{"role":"assistant","content":"Hello"}}],"model":"qwen-turbo"}
data:{"choices":[{"delta":{"content":" World"}}]}
data:{"choices":[{"finishReason":"stop"}]}
data:[DONE]
- Token 管理:确保
getToken函数能正确返回有效的认证 Token - 请求取消:建议在组件销毁时调用
abort()避免内存泄漏 - 错误处理:始终提供
onError回调处理异常情况 - CORS 配置:确保后端服务器正确配置 CORS 头
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
MIT License © 2025
感谢所有贡献者!
如果这个项目对您有帮助,请给一个 ⭐️ Star!