Automatically update the UI with Vue and trigger an event simultaneously

I have a v-for list of items that are derived from a list stored in Vuex. My goal is to ensure that the list automatically scrolls to the bottom each time a new item is added. I managed to implement the scrolling functionality by referring to this helpful resource: Scroll to bottom of div?

The basic idea behind achieving this is as follows:

addItem(){
    dispatch a Vuex event to add an item
    scroll to the bottom of the list
}

However, I encountered an issue where Vue seems to update the v-for list after the scrolling action takes place. As a result, the list always ends up scrolled to the second to last item instead of the very last one.

To address this issue, I temporarily resolved it by incorporating a setTimeout() function to introduce a 10ms delay. While this workaround works, it does feel somewhat hacky. Is there a more elegant and efficient way to trigger the scrollToBottom() function upon updating the v-for list?

Answer №1

If you're looking to wait for the next render in a Vue application, the standard method is to utilize

this.$nextTick(() => /* ... */)
. Check out this example:

new Vue({
  el: '#app',
  'store': new Vuex.Store({
    state: {
      items: ["a", "b", "c", "d"],
      index: 100
    },
    mutations: {
      itemAdded(state) {
        state.items.push(String.fromCharCode(++state.index));
      }
    },
    actions: {
      addItem({ commit }) {
        commit('itemAdded');
      }
    }
  }),
  computed: {
    ...Vuex.mapState(['items'])
  },
  mounted() { this.scrollToBottom(); },
  methods: {
    addItem() {
      this.$store.dispatch('addItem');
      this.$nextTick(() => this.scrollToBottom()); // <-------------------------
    },
    scrollToBottom() {
      this.$refs.list.scrollTop = this.$refs.list.scrollHeight;
    }
  }
});
ul { border: 1px solid black; height: 4em; overflow-y: scroll; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.5.1/vuex.min.js"></script>

<div id="app">
  <div>
    <button @click="addItem">Add item</button>
    <ul ref="list">
      <li v-for="(label, i) in items" :key="i">{{label}}</li>
    </ul>
  </div>
</div>

Answer №2

Implement async / await for dispatch function;

async addNew(){
   ensure asynchronous operation
   scroll to end of content
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Latest versions of Bootstrap are facing issues with the functionality of the Carousel feature

I'm struggling to create a basic carousel, but for some reason, it's not functioning properly. I attempted to use the sample code provided by Bootstrap's documentation, but it doesn't behave as expected (slides won't transition and ...

Updating the scope value in AngularJS with an asynchronous response is a crucial task for

I am facing an issue with sharing data between AngularJS controllers. The data is obtained through an http request, but when I try to access it in the controller, it returns null. Strangely, if I manually refresh through the UI, the data becomes available. ...

Load Materialize autocomplete with data from a JSON file

After hours of research, I am struggling to populate my autocomplete input using the Materialize plugin for a website project. Since I am not well-versed in json or ajax, implementing the original example from the documentation with static data has been qu ...

What is the best way to showcase the proper layout of my article, created using a WYSIWYG editor, with the help of Vue.js and Laravel

Can anyone provide guidance on how to display a customized article from a WYSIWYG editor using Vue.js? In Laravel, I am accustomed to using {!! $article->content !!} to show the full content. How can I achieve the same result in Vue.js using {{article ...

What is the best way to ensure a div occupies the full height within a grid layout?

https://i.sstatic.net/awwxE.png Looking at the image provided, I am seeking a way to make the top left image occupy the entire height just like the neighboring div in the first row of the grid. Is there a way to achieve this? The desired outcome should b ...

After diligently following every step on OneCheckout and getting no response when placing an order, I decided to upgrade my Magento version from 1.6.1.0 to 1.8

After upgrading the Magento version from 1.6.1.0 to 1.8.0, everything seems to be working smoothly. However, customers are facing an issue during checkout where they can't actually place their order. Despite following all the steps correctly, when t ...

Error: The jQuery function does not recognize the expression: #

The code successfully removes the "hidden" class from the designated object, but encounters an issue when trying to add it back. I have attempted various methods without any luck. Uncaught Error: Syntax error, unrecognized expression: # $(function() { ...

What is the best way to perform a deep sumBy operation with lodash?

var data= [{ "item_name": "Jumbo Combo", "item_key": "9lazhy15tp2fgo72", "item_price": 25, "quantity": 1, "ingredients": [{ "group_key": "fg1udvnz81qwpxtp", "key": "kcck54k7h3fzp5f0", ...

Updating a React component upon pressing a button to trigger a re-render

Currently, I am in the process of developing a React component that allows users to input an ID and retrieve relevant information upon submission. The code for this component is structured as follows: export default class IDContainer extends React.Componen ...

What is the best way to navigate through images only when hovering?

I have a website that showcases a collection of images in a creative mosaic layout. Upon page load, I assign an array of image links to each image div using data attributes. This means that every image in the mosaic has an associated array of image links. ...

Exploring the world of typescript with the power of ts-check

I'm having trouble figuring out how to work with a generic function using TypeScript's new ts-check feature. /** * @type {Reducer<IPoiState, any>} */ const poi = handleActions({ [ADD_BOOKMARK_START]: (state) => { return { ...sta ...

Numerous applications collaborating on workflows within a Firebase project

I am planning to create multiple Progressive Web App (PWA) sites under a single Firebase project. The idea is to make them accessible through different subdomains like app1.domain.com, app2.domain.com, and app3.domain.com. Even though these apps are conce ...

Set the background of the vue widget to be completely see-through

I have a project where I am creating a widget using Vuetify, and embedding it into another website in the following way: <!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="component-styl ...

Calculate the time difference between two dates using Moment JS

I have two specific dates that I need to calculate the duration between in a specific format ${y}year ${w}weeks ${d}days In order to achieve this, I have created a function. Here is the code snippet: setTotalDuration(): void { const formattedFrom = ...

The Ajax request was a success, but unfortunately the value in $_POST['value'] is empty

PROBLEM SOLVED The problem appeared to be browser-related. Switched to a different system and the issue was resolved. I am currently working on coding a live search feature that displays user details from a database using ajax and php. The input from t ...

Struggling with obtaining JSON data using Backbone.js

As I work through some tutorial code, I've come across the common practice of using a fake "json" object within the javascript file. However, I wanted to make my project more realistic by fetching the JSON data from a file hosted on a server. Despite ...

Oops! The Route.get() function in Node.js is throwing an error because it's expecting a callback function, but it received

Currently, I am learning how to create a web music admin panel where users can upload MP3 files. However, I have encountered the following errors: Error: Route.get() requires a callback function but received an [object Undefined] at Route. [as get] (C:&bso ...

Executing Auth0 API calls after logging in with Next.JS: A step-by-step guide

In my Next.JS app, I successfully set up auth0 login by following the documentation: // pages/api/auth/[...auth0].js import { handleAuth } from '@auth0/nextjs-auth0'; export default handleAuth(); // pages/index.js import { useUser } from ' ...

Obtain the URL value using jQuery and place it inside a <span> element

How can I insert a href value into the span tag like this? <p class="name"> <a download="adja-lo.pdf" title="adja-lo.pdf" href="http://localhost/MatrixDRSnews/apps/Matrix/server/php/files/adja-lo.pdf">adja-lo.pdf</a> </p> ...

Issue with Backbone: Browser button failing to activate routes

Recently, I have been working on a web application using backbone, jQuery, and the BAAS of stackmob. However, I've encountered an issue where browser buttons do not trigger the backbone routes as expected. Despite successfully navigating from one view ...