Search code examples
arraysvue.jssettimeoutv-for

How to loop over nested array in vue and display data every 5 seconds?


I'm using Vue Js and I have a nested array like this:

    arrays: [
      {
         name: 'Max',
         Info: [60, 75, 70, 85, 65], 
      },
      {
         name: 'Dave,
         Info: [70, 95, 60, 65, 83], 
      },
     ]

I have a user profile box that displays name and info for each user.

<div class="outer"  v-for="(item, index) in arrays" :key="item.id" v-bind:id="item.name">

I would like to display info in template:

<div class="box c" >Info<span v-for="info in item.Info">{{info}}</span></div> 

When I did this it showed the correct array for the correct user but it displayed all numbers but I would like info to show each number only for 5 seconds until the last number. So for Max it will display 60 then wait 5 seconds, then will only show 75 wait 5 seconds etc until it stops at the last number and only displays that number.

I tried creating a function :

  appendInfo: function() {
    
 for (let i = 0, l = this.arrays.length; i < l; i++) {
    let info = this.arrays[i]['Info'];
 
    
 let timer = 0;
   
    for (let i = 0; i < info.length; i++) {
      setTimeout(() => this.rate = info[i], timer);
      timer = timer + 5000;
      
  }
    
}

and passed data to rate

return {
      count: null, 
      rate: [],

and used {{rate}} in the template

<div class="box c" >Info<span>{{rate}}</span></div>

but it only displayed data from the second user profile for both profiles.

So I'm wondering if there is either a way to do this with v-for or how I can modify my function? Thanks!

Update

I used the RateDisplayer component like so:

<div class="outer"  v-for="(item, index) in arrays" :key="item.id" v-bind:id="item.name">
  <rate-displayer :rates="item.Info" />

import RateDisplayer from './RateDisplayer'
export default {
  name: 'card',
  props: {
            rates: {
                required: true,
            }
        
        },
  data () {
    return {
      interval: 5000,
      rate: false,
...

but still displayed only last arrays values.

Fixed

I removed from parent component:

props: {
            rates: {
                required: true,
            }

        },
 
      interval: 5000,
      rate: false,

and now it's working, thanks again!


Solution

  • I did something like that before. First, I suggest you to create a component JUST for this part:

    <div class="box c" >Info<span>{{rate}}</span></div>
    

    then, in this component you can accept rates as prop, and set rate every 5 sec to the new one. Something like:

    <template>
        <div class="box c" v-if="rate">Info<span>{{rate}}</span></div>
    </template>
    
     export default {
    
       name: "RateDisplayer.vue",
            props: {
                rates: {
                    required: true,
                }
            
            },
            data() {
                return {
                    interval: 5000,
                    rate: false
                }
            },
        mounted(){ this.nextOrStop(-1) },
        methods: { 
          nextOrStop(current)
          {
             if(current === this.rates.length-1) {  return }
             setTimeout( () => {
                 const index = current+1;
                 this.rate = this.rates[index];
                 this.nextOrStop(index)
                 }, this.interval)
    
        }
    
      ....
    

    You can insert this component inside your parent component like this:

    <div class="outer"  
         v-for="(item, index) in arrays" 
        :key="item.id" 
         v-bind:id="item.name">
    
             <rate-displayer :rates="item.Info" />
    </div>