-
+
+
+
+
{
}
};
+const contentRef = ref(null); // 滚动区域 DOM
+const autoScroll = ref(true); // 是否自动滚动
+
+/** 判断用户是否滚到了最底部 */
+const isAtBottom = () => {
+ const el = contentRef.value;
+ if (!el) return false;
+ const threshold = 10; // 收敛误差
+ let atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < threshold;
+ return atBottom
+};
+
+/** 滚动事件:只要用户滚动离开底部,就禁用自动滚动 */
+const onScroll = () => {
+ autoScroll.value = isAtBottom();
+};
+
+/** 自动滚动到底部 */
+const scrollToBottom = async () => {
+ await nextTick();
+ const el = contentRef.value;
+ if (!el) return;
+ el.scrollTo({
+ top: el.scrollHeight + 99999,
+ behavior: "smooth",
+ });
+
+ autoScroll.value = true;
+};
+
+/** 监听消息变化(AI 回答时) */
+const timer = ref(null);
+watch(messages.value, async (value) => {
+ if (autoScroll.value) {
+ await nextTick();
+ if (timer.value) {
+ clearTimeout(timer.value);
+ }
+ timer.value = setTimeout(() => {
+ scrollToBottom();
+ }, 200);
+ }
+});