简体   繁体   English

VueJS - 如何在数据更改时滚动底部

[英]VueJS - How to scroll bottom when data changes

In my component, I got a messages array.在我的组件中,我得到了一个消息数组。

data: function () {
        return {
            messages: [],
            first_load: false
            ...
        }

This messages array get initially populated with an Ajax call after the creation of my component.在我的组件创建后,这个消息数组最初会被一个 Ajax 调用填充。 After the data comes from the server I just push it into my messages variable, it paints all messages in the UI amazingly but after it gets pushed I try to scroll bottom my UI so the user watches only the latest content.在数据来自服务器后,我只是将其推送到我的消息变量中,它会惊人地在 UI 中绘制所有消息,但是在它被推送后,我尝试滚动 UI 底部,以便用户只观看最新的内容。

data.body.data.messages.map((message) => {
    this.messages.push(message)
}
this.scroll_bottom()

I noticed that performing a simple javascript scroll bottom line just after pushing my data won't work as the UI gets refreshed asynchronously (When i .push to my array it won't execute next line before syncing the UI), so I ended up adding a timeout and then scrolling bottom, but this is super shameful I think.我注意到在推送我的数据后执行简单的 javascript 滚动底线将不起作用,因为 UI 会异步刷新(当我 .push 到我的数组时,它不会在同步 UI 之前执行下一行),所以我结束了添加超时然后滚动底部,但我认为这非常可耻。

My hack:我的黑客:

watch: {
    messages:{
        handler: function (val, oldVal) {
            if (!this.first_load) {
                this.first_load = true
                setTimeout(() => {
                    this.scroll_bottom()
                }, 1000);
            }
        },
        deep: true
    }
}

Any ideas on how to leverage this?关于如何利用这一点的任何想法? Thanks!谢谢!

You can use updated life-cycle hook to do something after a DOM update.您可以在 DOM 更新后使用updated的生命周期挂钩来执行某些操作。 Take a look at the official documentation .看看官方文档

updated: function () {
    //scroll down logic here
}

If your updated logic is being called rapidly, you can always use a suitable denouncing method to slow down.如果你updated的逻辑被快速调用,你总是可以使用合适的谴责方法来减慢速度。

I think that watch is the right approach to that, but try using Vue.nextTick or this.$nextTick (to iterate just current component update cycle) instead of timeout:我认为 watch 是正确的方法,但尝试使用Vue.nextTickthis.$nextTick (仅迭代当前组件更新周期)而不是超时:

watch: {
    messages: function (val, oldVal) {
       // DOM not updated yet

       this.$nextTick(function () {
           // DOM updated

           this.first_load = true;
           this.scroll_bottom();
       });
    }
}

If your scrollable div's id is cont use the below method to scroll.如果您的可滚动 div 的 id 是cont使用下面的方法滚动。

scroll() {
  document.getElementById('cont').scrollTop = document.getElementById('cont').scrollHeight;
}

And you have to call this inside updated hook.你必须在updated的钩子中调用它。

updated() {
  this.scroll();
}

在 v-for 之前在 div 中使用 v-chat-scroll

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM