feat: 对话滚动的调整

This commit is contained in:
2025-11-26 21:15:33 +08:00
parent 6cdd5279a3
commit 05625829d0
5 changed files with 63 additions and 6 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -10,9 +10,13 @@ import McChat from './components/McChat.vue';
<style scoped> <style scoped>
.app-container { .app-container {
height: 100vh; height: calc(100vh - 16px);
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
} }
:deep(.mc-bubble) {
gap: 8px !important;
}
</style> </style>

View File

@@ -83,4 +83,5 @@ body {
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -23,7 +23,8 @@
@itemClick="onSubmit($event.label)" @itemClick="onSubmit($event.label)"
></McPrompt> ></McPrompt>
</McLayoutContent> </McLayoutContent>
<McLayoutContent class="content-container" v-else> <McLayoutContent v-else>
<div class="content-container" ref="contentRef" @scroll="onScroll">
<template v-for="(msg, idx) in messages" :key="idx"> <template v-for="(msg, idx) in messages" :key="idx">
<McBubble <McBubble
v-if="msg.from === 'user'" v-if="msg.from === 'user'"
@@ -36,6 +37,7 @@
<McMarkdownCard :content="msg.content"> </McMarkdownCard> <McMarkdownCard :content="msg.content"> </McMarkdownCard>
</McBubble> </McBubble>
</template> </template>
</div>
</McLayoutContent> </McLayoutContent>
<div class="shortcut" style="display: flex; align-items: center; gap: 8px"> <div class="shortcut" style="display: flex; align-items: center; gap: 8px">
<McPrompt <McPrompt
@@ -81,7 +83,7 @@ import logoImg from '@/assets/logo.png';
import avatarImg from '@/assets/chat_avatar.svg'; import avatarImg from '@/assets/chat_avatar.svg';
import chatLogoImg from '@/assets/chat_logo.png'; import chatLogoImg from '@/assets/chat_logo.png';
import { ref } from 'vue'; import { ref, watch, nextTick } from 'vue';
import { Button } from 'vue-devui/button'; import { Button } from 'vue-devui/button';
import 'vue-devui/button/style.css'; import 'vue-devui/button/style.css';
import { CozeAPI } from "@coze/api"; import { CozeAPI } from "@coze/api";
@@ -135,7 +137,7 @@ const inputFootIcons = [
]; ];
const apiClient = new CozeAPI({ const apiClient = new CozeAPI({
token: "cztei_lZ7Dx1q6NKcVFg0d6iT0Aesdmo5vnhgBH7TCacaxEBk9D2fIBTOwNCgxFh0a7Vo7Z", token: "sat_V4vKS7SSOpYg15gvD0i0xBgQFc0D30Bj6EjMMt1eSPSCl9SKj2tCNLTEw4g4hyGa",
baseURL: "https://api.coze.cn", baseURL: "https://api.coze.cn",
}); });
@@ -199,6 +201,49 @@ const onSubmit = async (evt) => {
} }
}; };
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);
}
});
</script> </script>
<style> <style>
@@ -216,8 +261,15 @@ const onSubmit = async (evt) => {
.content-container { .content-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%;
gap: 8px; gap: 8px;
overflow: auto; overflow: auto; /* 或 scroll */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE & Edge */
}
.content-container::-webkit-scrollbar {
display: none; /* Chrome / Safari / Edge / Opera */
} }
.input-foot-wrapper { .input-foot-wrapper {