简体   繁体   中英

TailwindCSS animation doesn't work with v-for

I'm trying to create a list of pop messages in the right top part of the screen. On click this message goes away. Each popup message is a part of slide-fade Transition.

When I have only one popup component, the animation works, however with more than 1 the animation doesn't work. I would really appreciate if anyone can help me out with this problem. Thanks in advance.

Here's the code:

popup.vue

<template>
    <Transition name="slide-fade" @click="close">
        <div class="bg-green-100 opacity-95 rounded-lg py-5 px-6 mb-3 text-green-700 inline-flex items-center text-sm" role="alert">
            <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="w-8 h-8 mr-2 fill-current" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                <path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path>
            </svg>
            {{ placeholder }}
        </div>
    </Transition>
</template>

<script>
export default {
    name: 'popupComponent',
    methods: {
        close () {
            this.$emit('close', this.arrIndex)
        }
    },
    props: {
        placeholder: String, 
        arrIndex: Number
    }
}
</script>

<style scoped>
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}

.slide-fade-leave-active {
  transition: all 0.8s cubic-bezier(.25,.59,.63,.92);
}

.slide-fade-enter-from,
.slide-fade-leave-to {
  transform: translateX(20px);
  opacity: 0;
}
</style>

App.vue :

<template>
  <div class="absolute z-10 right-0 p-2 max-w-md">
     <div class="flex flex-col gap-y-2 max-h-96 overflow-y-hidden">
        <popup v-for="(content, index) in popup_content.slice().reverse()" :key="index" @close="closePopup" :arrIndex="(popup_status.length-1) - index"  :placeholder="content"/>
     </div>  
  </div>
</template>

<script>
import popupComponent from './components/popup.vue'

export default {
  data() {
    return {
      popup_content: ['Awesome!', 'Nice!'],
    }
  },
  methods: {
    closePopup(index) {
      this.popup_content.splice(index, 1);
    }
  },
  components: {
    'popup': popupComponent
  },
  name: 'App'
}
</script>

This might be because you use an index as a key.

You should not use index as a key of the v-for in your case. Use a unique, non-changing identifier, like an id or in your example the content.

Vue relies on the key to detect changes in the DOM. With your close function, you delete an item from the array, eg if you close the first message, this causes the second message getting index 0, instead of 1. This can cause the strange behavior you are experiencing.

See docs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM