组件/Conversation Stream

Conversation Stream

虚拟滚动的会话流,自动吸底并向上翻取历史。

Verified自 0.3.9

Conversation Stream

基础用法

Conversation Stream

示例加载中...

交互契约

  • 组件是泛型的(<T>):items 的元素类型会一路传到 item 插槽的作用域参数上,无需另行断言。
  • itemKey 必填。虚拟化依赖稳定的 key 做位置缓存,用数组下标会在插入消息时错位。
  • estimatedItemHeight 只是首次布局的估值;元素真实高度测出来后会自动校正。
  • 吸底是有条件的:用户停在底部时新消息会跟随;一旦向上滚动就不再强行拉回,改为显示「回到底部」提示。
  • streaming 只影响这个提示的「有新内容」状态,不影响是否吸底。
  • loadOlder 在接近顶部时被调用,约定是消费方自己把数据前插进 items,然后 resolve { hasMore }。组件不持有消息数组。
  • 前插历史后会保持视口锚点,不会把用户弹到别处。
  • hasMoreInitial 的默认值是显式的 undefined 而非 false:这是为了绕开 Vue 对缺省 Boolean prop 的 false 转换,让「还没问过」与「确实没有更早的了」保持可区分。若你确定没有历史,请显式传 false
  • loadOlder 抛错时派发 load-error,并渲染 top-error 插槽,其作用域参数带 retry

API

Props

属性名类型默认值说明
itemsT[]消息数组。必填。
itemKeyConversationStreamItemKey<T>取稳定 key 的函数。必填。
estimatedItemHeightnumber96未测量元素的假定高度。
overscannumber4可视区上下各多渲染的条数。
loadOlder() => Promise<ConversationStreamLoadResult>接近顶部时调用;前插数据后 resolve { hasMore }
hasMoreInitialbooleanundefined首次 loadOlder 返回前是否可能存在历史。
streamingbooleanfalse驱动「回到底部」提示的新内容状态。

Events

事件名参数说明
at-bottom-change(atBottom: boolean)吸底状态变化时派发。
load-error(error: unknown)loadOlder 抛错时派发。

Exposed

名称类型说明
scrollToBottom() => void滚动到底部。
scrollToIndex(index: number) => void滚动到指定索引。
atBottomComputedRef<boolean>当前是否处于底部,只读。

Slots

插槽名作用域参数说明
item{ item: T, index: number }渲染单条消息。
emptyitems 为空时的占位。
top-loading正在加载更早消息。
top-error{ retry: () => void }加载失败,带重试回调。
top-done已无更早消息。
scroll-to-bottom{ streaming: boolean }自定义「回到底部」提示。

最佳实践

  • itemKey 用消息自身的 id,不要用下标——这是虚拟化正确性的前提,不是优化项。
  • loadOlder 里要自己前插数据;只 resolve 不改 items 会让组件一直以为还有历史可加载。
  • 确认没有更早消息时显式传 hasMoreInitial: false,不要依赖默认值——默认的 undefined 表示「未知」。
  • estimatedItemHeight 尽量贴近真实平均高度,差得太远时首屏滚动条会明显跳动。
  • 需要程序化跳转时用暴露的 scrollToBottom / scrollToIndex,不要自己去操作滚动容器,否则会与吸底逻辑打架。