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

Javascript VueJS-如何在数据更改时滚动底部,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,在我的组件中,我得到了一个消息数组 data: function () { return { messages: [], first_load: false ... } 在创建我的组件之后,这个消息数组最初由一个Ajax调用填充。数据来自服务器后,我只需将其推入我的messages变量,它会在UI中绘制所有消息,令人惊讶,但在推送数据后,我尝试在UI底部滚动,以便用户只查看最新的内容 dat

在我的组件中,我得到了一个消息数组

data: function () {
        return {
            messages: [],
            first_load: false
            ...
        }
在创建我的组件之后,这个消息数组最初由一个Ajax调用填充。数据来自服务器后,我只需将其推入我的messages变量,它会在UI中绘制所有消息,令人惊讶,但在推送数据后,我尝试在UI底部滚动,以便用户只查看最新的内容

data.body.data.messages.map((message) => {
    this.messages.push(message)
}
this.scroll_bottom()
我注意到,在推送数据之后执行简单的javascript滚动底线将无法工作,因为UI会异步刷新(当我将.push推送到我的数组时,它不会在同步UI之前执行下一行),所以我最后添加了一个超时,然后滚动底线,但我认为这是非常可耻的

我的黑客:

watch: {
    messages:{
        handler: function (val, oldVal) {
            if (!this.first_load) {
                this.first_load = true
                setTimeout(() => {
                    this.scroll_bottom()
                }, 1000);
            }
        },
        deep: true
    }
}
关于如何利用这一点有什么想法吗?
谢谢

您可以使用
updated
life-cycle钩子在DOM更新后执行某些操作。请看下面的图片


如果正在快速调用
更新的
逻辑,则始终可以使用适当的退出方法来降低速度。

如果可滚动div的id为
cont
,请使用以下方法滚动

scroll() {
  document.getElementById('cont').scrollTop = document.getElementById('cont').scrollHeight;
}
你必须在
updated
hook中调用它

updated() {
  this.scroll();
}

我认为watch是正确的方法,但请尝试使用
Vue.nextTick
this.$nextTick
(仅迭代当前组件更新周期)而不是超时:

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

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

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

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

我认为使用超时没有那么糟糕。您可以清除现有超时,并在新数据出现时创建一个新的超时。此外,您还可以使用解盎司功能来避免快速创建超时。请查看Vue生命周期挂钩,您可以使用“beforeUpdate”和“Update”挂钩来计时滚动。您是否尝试过下一步?这就是您要查找的吗@nipunasudha感谢您的评论,实际上这是一个很好的想法。我刚刚读了“更新”的方法,这就是我理论上想要的。我只是尝试了一下,效果很好,只是出于某种原因,我对我的数据做了很多更改,所以它有一些问题,但从理论上讲,这是答案,如果你想继续并发布它的话。
watch: {
    messages: function (val, oldVal) {
       // DOM not updated yet

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

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