Animating duplicate list items added with v-for

190 views Asked by At

I want to animate list items in a loop with vue's transition group. I want always the added item to be animated. But I always got the last one animated. Research in docs/questions indicated this normally is a keying problem: Key needs unique id. Now I can't take the IDs from the array I'm outputting there, as I'm outputting randomly, so keys would be duplicate (actually I get a duplicate elements console error).

So I built on this suggestion to get a unique id.

script:

data: function() {
       return {
       logId: 1,
       },

methods: {
randomize () {
        if (this.activeAudio) {
          this.pause();
          this.activeAudio = null;
        }
        var chosenNumber = Math.floor(Math.random() * this.audios.length);
        this.activeAudio = this.audios[chosenNumber];
        this.activeAudio.isPlaying = true;
        this.activeAudio.file.play();
        this.activeAudio.file.loop = true;
        this.audioLogItems.unshift({
            text: this.activeAudio.name
        });

        this.logId++;
        this.audioLogItems.push({id: this.logId});
       },
} 

template:

<transition-group name="baseLogList" tag="ul">
                    <li v-for="(audioLogItem, id) in audioLogItems" 
                    :key="id"
                    @click="this.audioLogItem.file.play()">
                      {{ audioLogItem.text }}
                    </li> 
                  </transition-group>

CSS:

.baseLogList {
  display:block
}
.baseLogList-enter-active, .baseLogList-leave-active {
  transition: all .5s;
}
.baseLogList-enter, .baseLogList-leave-to /* .fade-in-leave-active below version 2.1.8 */ {
  opacity: 0;
}

Outputting {{ audioLogItem.id }} instead of {{ audioLogItem.text }} actually gives me 2, 3, 4 and so on each click. But it doesn't seem it can be used in the loop, as still always the last children gets animated, not the first.

My question: How can I manage to always get the added item to be animated, so the first one in the list?

1

There are 1 answers

1
Radu Diță On

You are pushing at the end of the audioLogItems array.

If you want to see the first element being animated, you need to push it at the head of the array.

Try to use unshift.

this.audioLogItems.unshift({id: this.logId});