<div id="app">
    <p>Scroll down with DOM update</p>
    <div ref="box1" class="box box1">
      <div v-for="(message, key) in messages" :key="key">{{message.body}}</div>
      ...
    </div>
    <button v-on:click="addMessage1">Add message</button>
    <br>
    <p>Scroll down after DOM update</p>
    <div ref="box2" class="box box2">
      <div v-for="(message, key) in messages" :key="key">{{message.body}}</div>
      ...
    </div>
    <button v-on:click="addMessage2">Add message</button>
  </div>
.box {
  height: 100px;
  width: 300px;
  overflow: scroll;
  border: 1px solid #000
}
new Vue({
  el: '#app',
  data: () => {
    return {
      messages: [
        { body: "Message 1" },
        { body: "Message 2" },
        { body: "Message 3" },
        { body: "Message 4" },
        { body: "Message 5" }
      ]
    };
  },
  methods: {
    async addMessage1() {
      this.messages.push({ body: `Message ${this.messages.length+1}`})
      this.$refs.box1.scrollTop = this.$refs.box1.scrollHeight
    },
    async addMessage2() {
      this.messages.push({ body: `Message ${this.messages.length+1}`})

      await this.$nextTick()

      this.$refs.box2.scrollTop = this.$refs.box2.scrollHeight
    }
  }
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/vue/dist/vue.js