1. 需求
适用于以下几种需求
- 添加一条消息,自动滚动最下方
- 挂载时,加载接口后,自动滚动到最下方
- websoket发送消息实时滚动最下方
2. 代码
// ============================
// 消息列表
// ============================
<div
class="msgs"
v-for="(item, index) in msgList"
:key="index"
:style="{
flexDirection:
item.userId === store.getters.user.id ? 'row-reverse' : 'row',
}"
ref="child"
>
</div>
// ============================
// 发送一条消息,往msgList.push(msg),因此watch(msgList...)
// ============================
<script setup> // 使用vue3 语法糖,暂无使用ts,差别不大
const state = reactive({
msgList: [],
message: '',
});
const child = ref();
watch(
() => state.msgList,
(newVal) => {
nextTick(() => {
child.value[newVal.length - 1].scrollIntoView(); // 关键代码
});
},
{
deep: true,
}
);
</script>
注:scrollIntoView() 方法来将元素滚动到视口的指定位置。
这里child.value是一个数组,我们希望child的数组最后一个元素滚动到视口顶部。
nextTick不可缺少
3. 补充
注:像消息这样,左右消息刚好是相反的,我们可以借助
flex的一个属性来处理:{ flexDirection: item.userId === store.getters.user.id ? 'row-reverse' : 'row', } 如上文代码中所示