I am trying to watch
a computed value that gets filled up with messages from a store. This is it (code reduced for brevity):
<div ref="RefWindow">
<ul v-for="Message in Feed">
<li>Message</li>
</ul>
</div>
const Feed = computed(() => MyStore.Messages)
const RefWindow = ref();
function scrollToBottom() {
console.log(`scrollTop: ${RefWindow.value.scrollTop}, scrollHeight: ${RefWindow.value.scrollHeight}`)
RefWindow.value.scrollTop = RefWindow.value.scrollHeight; // Scrolls to bottom
}
watch(() => Feed, async () => {
await nextTick();
scrollToBottom(); // Doesn't work console.log shows scrollTop: 0, scrollHeight: 0
setTimeout(()=> scrollToBottom(), 20); // Works console.log shows scrollTop: 0, scrollHeight: 4203
}
}, {
immediate: true,
deep: true
})
It was my understanding that nextTick()
is almost like onUpdated
lifecycle hook in that once Feed
‘s value has changed, on the next update of the DOM the code should run. However without the setTimeout
in place it seems the scrollHeight
of the div RefWindow
is not being updated.
What is the correct way to go about this without using a timeout?
2
Answers
It’s not clear what happens since you didn’t provide your full template and better MRE.
You could try
flush: 'post'
option for the watch:https://vuejs.org/guide/essentials/watchers#post-watchers
Just use a directive:
Playground