feat: 对话滚动的调整
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 6.8 KiB |
@@ -10,9 +10,13 @@ import McChat from './components/McChat.vue';
|
||||
|
||||
<style scoped>
|
||||
.app-container {
|
||||
height: 100vh;
|
||||
height: calc(100vh - 16px);
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:deep(.mc-bubble) {
|
||||
gap: 8px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -83,4 +83,5 @@ body {
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 6.8 KiB |
@@ -23,8 +23,9 @@
|
||||
@itemClick="onSubmit($event.label)"
|
||||
></McPrompt>
|
||||
</McLayoutContent>
|
||||
<McLayoutContent class="content-container" v-else>
|
||||
<template v-for="(msg, idx) in messages" :key="idx">
|
||||
<McLayoutContent v-else>
|
||||
<div class="content-container" ref="contentRef" @scroll="onScroll">
|
||||
<template v-for="(msg, idx) in messages" :key="idx">
|
||||
<McBubble
|
||||
v-if="msg.from === 'user'"
|
||||
:content="msg.content"
|
||||
@@ -36,6 +37,7 @@
|
||||
<McMarkdownCard :content="msg.content"> </McMarkdownCard>
|
||||
</McBubble>
|
||||
</template>
|
||||
</div>
|
||||
</McLayoutContent>
|
||||
<div class="shortcut" style="display: flex; align-items: center; gap: 8px">
|
||||
<McPrompt
|
||||
@@ -81,7 +83,7 @@ import logoImg from '@/assets/logo.png';
|
||||
import avatarImg from '@/assets/chat_avatar.svg';
|
||||
import chatLogoImg from '@/assets/chat_logo.png';
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch, nextTick } from 'vue';
|
||||
import { Button } from 'vue-devui/button';
|
||||
import 'vue-devui/button/style.css';
|
||||
import { CozeAPI } from "@coze/api";
|
||||
@@ -135,7 +137,7 @@ const inputFootIcons = [
|
||||
];
|
||||
|
||||
const apiClient = new CozeAPI({
|
||||
token: "cztei_lZ7Dx1q6NKcVFg0d6iT0Aesdmo5vnhgBH7TCacaxEBk9D2fIBTOwNCgxFh0a7Vo7Z",
|
||||
token: "sat_V4vKS7SSOpYg15gvD0i0xBgQFc0D30Bj6EjMMt1eSPSCl9SKj2tCNLTEw4g4hyGa",
|
||||
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>
|
||||
|
||||
<style>
|
||||
@@ -216,8 +261,15 @@ const onSubmit = async (evt) => {
|
||||
.content-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user