开发一个问答功能,后台采用SSE流式输出。前端 vue3,vite。流式输出前端使用@microsoft/fetch-event-source包实现。
目前问题:程序正常进入了onmessage回调,但是vue3没有监测到数据更新,导致界面上的数据没变化。前端代码如下:
<script setup>
import { nextTick, ref,watchEffect,getCurrentInstance,reactive } from 'vue'
import {
fetchEventSource,
EventStreamContentType
} from "@microsoft/fetch-event-source";
defineProps({
msg: String,
})
const controller = new AbortController();
const signal = controller.signal;
const count = ref(0)
let messages = ref("");
const instance = getCurrentInstance();
watchEffect(() => {
console.log(`count 的当前值是 ${messages.value}`);
// 这里的副作用会随着 count 的变化自动执行
});
const forceUpdate = () => {
const instance = getCurrentInstance();
if (instance) {
instance.proxy?.$forceUpdate();
}
};
const postData = {
query: "你好",
knowledge_base_id: 1,
history: []
};
messages.value="keisssss"
// 确保你的 setup 或 methods 能够使用 async 函数
async function handleSSEMessage(event) {
try {
const jsonObj = event.data;
const data = JSON.parse(jsonObj);
messages.value+=data["gpt_response"]
console.log(messages)
// 如果你需要在数据添加后执行某些基于DOM的操作或确保视图已更新,可以使用nextTick
nextTick(() => {
// 这里可以安全地基于更新后的 DOM 进行操作
console.log('DOM 已经更新');
// 例如,获取元素的新高度
});
// 进行后续操作...
} catch (error) {
console.error('Error parsing SSE message:', error);
}
}
const fetchChatAPIOnce = async () => {
debugger
await fetchEventSource("http://127.0.0.1:8000/api/v1/knowledge/search_question", {
method: "POST", // 指定请求方法为POST
signal: signal,
headers: {
"Content-Type": "application/json" // 设置正确的Content-Type
},
body: JSON.stringify(postData), // 设置请求体为JSON字符串
async onopen(response) {
debugger;
if (
response.ok &&
response.headers.get("content-type") === EventStreamContentType
) {
return; // everything's good
} else if (
response.status >= 400 &&
resow new Error();
},
openWhenHidden: true
});
};
fetchChatAPIOnce()
</script>
<template>
<div>{{ messages }}</div>
</template>ponse.status < 500 &&
response.status !== 429
) {
// client-side errors are usually non-retriable:
} else {
}
},
onmessage(event) {
handleSSEMessage(event)
},
onerror(err) {
controller.abort();
throw new Error();
},
onclose() {
//正常结束的回调
controller.abort(); //关闭连接
// throw new Error();
},
openWhenHidden: true
});
};
fetchChatAPIOnce()
</script>
<template>
<div>{{ messages }}</div>
</template>