最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - VueJS - How to scroll bottom when data changes - Stack Overflow

programmeradmin4浏览0评论

In my ponent, 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 ponent. After the data es 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.

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.

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!

In my ponent, 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 ponent. After the data es 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.

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.

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!

Share Improve this question edited Aug 15, 2018 at 4:19 Sumithran 6,5657 gold badges43 silver badges58 bronze badges asked Aug 15, 2018 at 3:52 damuz91damuz91 1,7382 gold badges27 silver badges43 bronze badges 6
  • 1 I don't think using a timeout is that bad. You can clear the existing timeout and create a new one when the new data es. Also you can use a debounce function to avoid rapid timeout creation. – nipunasudha Commented Aug 15, 2018 at 4:04
  • 1 Take a look at Vue life-cycle hooks vuejs/v2/guide/instance.html you can use 'beforeUpdate' & 'updated' hooks for timing your scrolling. – nipunasudha Commented Aug 15, 2018 at 4:09
  • 1 have you tried nextTick ? – Jacob Goh Commented Aug 15, 2018 at 4:16
  • 1 Is this what you're looking for? stackoverflow./q/40730116/2813263 – Domino Commented Aug 15, 2018 at 4:22
  • @nipunasudha Thanks for your ment, actually is quite a good thought. I just read the 'updated' method and that is what in theory im looking for. I just tried and it works good, except that for some reason i am doing a lot of changes to my data so it has some problems, but again in theory this is the answer, if you want go ahead and post it. – damuz91 Commented Aug 15, 2018 at 4:30
 |  Show 1 more ment

4 Answers 4

Reset to default 6

You can use updated life-cycle hook to do something after a DOM update. 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.

I think that watch is the right approach to that, but try using Vue.nextTick or this.$nextTick (to iterate just current ponent update cycle) instead of timeout:

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.

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

And you have to call this inside updated hook.

updated() {
  this.scroll();
}

Use v-chat-scroll in div before v-for

发布评论

评论列表(0)

  1. 暂无评论