2

I have a project in Vue where I need to show images. These images are contained inside a. When the page is loaded I want the images to fade in one at a time. I have added a transition group with a fade in effect and added a function where each image gets added with a small delay.

I don't seem to get the images to show up after each others. The images show up all at once.

I have tried to put my code into the snipper below. But I don't seem to get the href source to get bounded. In my project i use local images stored in the assets/img folder.

<!DOCTYPE html>
<html>

<head>
  <title></title>
  <script src="https://unpkg.com/vue"></script>
</head>

<body>
  <transition-group name="fade">
    <div v-for="logo in logos" :key="logo.id">
      <img :src="logo.filename" alt="">
    </div>
  </transition-group>

  <script>
    new Vue({
      el: '',
      data() {
        return {
          logos: []
        }
      },
      mounted() {
        const addedLogos = [{
            id: 1,
            filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
          },
          {
            id: 2,
            filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
          },
          {
            id: 3,
            filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
          },
          {
            id: 4,
            filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
          },
          {
            id: 5,
            filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
          },
          {
            id: 6,
            filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
          },
        ]
        addedLogos.forEach(logo => {
          setTimeout(() => {
            const newLogos = this.logos
            newLogos.push(logo)
            this.logos = newLogos
          }, 100)
        })
      }
    });
  </script>
  <style scoped>
    .fade-enter-active,
    .fade-leave-active {
      transition: opacity .5s;
    }
    
    .fade-enter,
    .fade-leave-to {
      opacity: 0;
    }
  </style>
</body>

</html>
Dan
  • 59,490
  • 13
  • 101
  • 110
Stephen
  • 913
  • 3
  • 24
  • 50

1 Answers1

1

All of the setTimeout calls happen immediately. They don't delay the loop and cause the next iteration to wait, so each image is scheduled to show at the same time.

You could use the forEach loop index to schedule them incrementally:

addedLogos.forEach((logo, index) => {
  setTimeout(() => {
    const newLogos = this.logos
    newLogos.push(logo)
    this.logos = newLogos
  }, 100 * (index + 1))
})

Here's a demo:

new Vue({
  el: "#app",
  data() {
    return {
      logos: []
    }
  },
  mounted() {
    const addedLogos = [{
      id: 1,
      filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
    },{
      id: 2,
      filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
    },{
      id: 3,
      filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
    },{
      id: 4,
      filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
    },{
      id: 5,
      filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
    },{
      id: 6,
      filename: 'http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png'
    }]

    addedLogos.forEach((logo, index) => {
      setTimeout(() => {
        const newLogos = this.logos
        newLogos.push(logo)
        this.logos = newLogos
      }, 100 * (index + 1))
    })
    
  }
})
div div, div div img {
  display: inline-block;
  width: 50px;
  height: 50px;
}
<div id="app">
  <transition-group name="fade">
    <div v-for="logo in logos" :key="logo.id">
      <img :src="logo.filename" alt="">
    </div>
  </transition-group>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
Dan
  • 59,490
  • 13
  • 101
  • 110