Vue Transition not Triggering on button click

前端 未结 2 1008
北海茫月
北海茫月 2020-12-21 08:16

I am new to Vue JS and I am creating a thumbnail viewer wherein I\'ll be getting a list of images and videos as an array of objects. At first, I will be showing just 5 items

2条回答
  •  旧巷少年郎
    2020-12-21 08:56

    No transition issue you met is caused by :key="index".

    Check Vue Guide: key of v-for,

    When Vue is updating a list of elements rendered with v-for, by default it uses an “in-place patch” strategy.

    This default mode is efficient, but only suitable when your list render output does not rely on child component state or temporary DOM state (e.g. form input values).

    To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item.

    In your codes, your five images always have the same key=[1, 2, 3, 4, 5], so Vue will in-place patch them, it causes the transition is not triggered.

    So simply modify the :key="index" to :key="item.itemImageAlt", then it works.

    Finally, adjust the css by yourself to make the transition effetcs meet your requirements.

    Below is one working demo:

    Vue.config.productionTip = false
    new Vue({
      el: "#app",
      data() {
        return {
          totalCarouselData: [
            {
              itemImage:
                "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
              itemImageAlt: "Test1"
            },
            {
              itemImage:
                "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
              itemImageAlt: "Test2"
            },
            {
              itemImage:
                "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
              itemImageAlt: "Test3"
            },
            {
              itemImage:
                "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
              itemImageAlt: "Test4"
            },
            {
              itemImage:
                "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
              itemImageAlt: "Test5"
            },
            {
              itemImage:
                "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
              itemImageAlt: "Test6"
            },
            {
              itemImage:
                "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
              itemImageAlt: "Test7"
            }
          ],
          currentCarouselData: [],
          isSlidingToPrevious: false,
          totalCount: 0,
          currentTopIndex: 0,
          currentBottomIndex: 0,
          itemsToDisplay: 5
        };
      },
      computed: {
        computedCarouseData: function () { // added computed property
            return this.totalCarouselData.slice(
            -this.currentTopIndex,
            this.itemsToDisplay-this.currentTopIndex
          )
        }
      },
      mounted() {
        //At first show only 5 items
        this.currentCarouselData = this.totalCarouselData.slice(
          this.currentTopIndex,
          this.itemsToDisplay
        );
        //Get Total Count
        this.totalCount = this.totalCarouselData.length;
        //Update current bottom index
        this.currentBottomIndex = this.itemsToDisplay;
      },
      methods: {
        moveTop() {
          this.isSlidingToPrevious = true;
          this.currentTopIndex += 1;
          this.currentBottomIndex -= 1;
          this.addToTopComputedArr(this.currentBottomIndex);
        },
        moveBottom() {
          this.isSlidingToPrevious = false;
          this.currentTopIndex -= 1;
          this.currentBottomIndex += 1;
          this.addToBottomComputedArr(this.currentBottomIndex);
        },
        addToBottomComputedArr(index) {
          //Splice the first item
          this.currentCarouselData.splice(0, 1);
          //Add the next item to the array
          this.currentCarouselData.push(this.totalCarouselData[index - 1]);
        },
        addToTopComputedArr(index) {
          //Splice the last item
          this.currentCarouselData.splice(index - 1, 1);
          //Add item to the beginning of the array
          this.currentCarouselData.unshift(
            this.totalCarouselData[index - this.itemsToDisplay]
          );
        }
      }
    });
    .row-eq-height {
      display: flex;
    }
    .row-eq-height ul {
      list-style-type: none;
      display: flex;
      flex-direction: column;
      overflow: hidden;
      height: auto;
      border: 1px solid black;
    }
    .row-eq-height li {
      flex: 1;
      width: 64px;
      height: 64px;
      position: relative;
      margin: 8px 0;
      border: 1px solid red;
    }
    .row-eq-height li img {
      max-width: 100%;
      max-height: 100%;
    }
    .list-leave-active,
    .list-enter-active {
      transition: all 2s ease;
    }
    .list-enter {
      opacity: 0;
      transform: translateX(-300px);
    }
    .list-leave-to {
      opacity: 0;
      transform: translateX(-300px);
    }
    .sliding-to-previous .list-enter {
      transform: translateY(-100px);
    }
    .sliding-to-previous .list-leave-to {
      transform: translateY(100px);
    }
    .list-move {
      transition: transform 1s;
    }
    
    
  • {{item.itemImageAlt}}
  •     totalCount {{totalCount}}
        currentTopIndex {{currentTopIndex}}
        currentBottomIndex {{currentBottomIndex}}
        itemsToDisplay {{itemsToDisplay}}
        currentCarouselData {{computedCarouseData}}
    

提交回复
热议问题