I use v-for
to render the message list. when the first batch of messages are rendered, I use scrollIntoView()
on the newest one so the container scrolls to bottom. as the user scrolls up I fetch previous messages to create a seamless scroll.
the problem is that when new messages are rendered, the scroll goes to the top of the container.
I tried saving the first message id in the list before updating the list with fetched messages and then scrolling back to that message but it causes a jump on the screen for a moment and is not a good user experience.
how can I prepend and render older messages to the message list so that current messages stay in their place wherever they are on the screen?
message list is stores in vuex and I update it using this action:
HandleMessageList({state, commit}, msgList) { const currentMessages = state.messages const updatedMessages = msgList.concat(currentMessages) commit('SET_MESSAGES', updatedMessages) }
and in template:
<template> <div class=msg-container" ref="messageDisplayArea"> <message-object v-for="msg in msgList" :key="msg.id" /> </div> </template> <script> import {mapState} from "vuex"; export default { name: "MessageDisplay", components: { MessageObject, }, computed: { ...mapState({ msgList: state => state.messages, }), }, updated() { this.$nextTick(() => this.scrollToTarget()) }, mounted() { this.$refs.messageDisplayArea.addEventListener('scroll', this.handleUserScroll) }, beforeDestroy() { this.$refs.messageDisplayArea.removeEventListener('scroll', this.handleUserScroll) }, methods: { scrollToTarget() { // ... scroll back to the position before message list update }, handleUserScroll(e) { const scrollTop = e.target.scrollTop const scrollHeight = e.target.scrollHeight const elementHeight = e.target.offsetHeight if (scrollTop === 0 && elementHeight < scrollHeight) { // ... fetch older messages } }, }, } </script>
versions:
vue 2.6.10 vuex 3.0.1
Advertisement
Answer
I found the behavior I wanted in this Quasar component
it is an infinite scroll component but the main part is that the scroll can be in reverse which is necessary for a chat message scroll.