【问题标题】:Vue.js transition and transition-group animations not workingVue.js 过渡和过渡组动画不起作用
【发布时间】:2018-02-28 15:22:22
【问题描述】:

我有一个 Vue 2 Carousel 组件,其中 Slide 子组件使用 v-for 生成。使用v-show 显示和隐藏幻灯片。我无法让幻灯片之间的 CSS transitions 正常工作。

我尝试将幻灯片包裹在 <transition> 中,但 mode=out-in 什么也没做,在过渡期间我最终在轮播中出现了两张幻灯片,一张淡入,另一张淡出。当我将幻灯片包裹在 <transition-group> 中时,CSS transitions 根本不显示,幻灯片只是被替换了。

我查看了transitioning between components,但幻灯片是根据来自 API 的链接列表生成的,我没有看到将动态生成与此解决方案相结合的方法。

这是JSFiddle with the issue

【问题讨论】:

    标签: vue.js vuejs2 css-transitions


    【解决方案1】:

    如果您不打算交叉淡入淡出图像(即在任何给定时间点实际上只有一个图像在屏幕上),您可以重组您的代码,例如一次只渲染一个 <Slide> 组件.您只需分配一个动态更新的唯一键,例如您的滑块组件的active 数据。

    您的模板现在将如下所示:

    <div class="carousel-wrapper" id="promotions">
        <transition name="component-fade" mode="out-in">
            <!-- Bind image url dynamically, bind key to active index -->
            <Slide class="slide" :url="imageUrl" :key="active"></Slide>
        </transition>
    </div>
    

    imageUrl 只是一个按索引返回图像 URL 的计算属性:

    imageUrl() {
        return this.list[this.active].url;
    }
    

    Slide 组件应该像我们需要的那样“愚蠢”:在这种情况下,它只接收动态绑定的图像 URL,仅此而已:

    <div>
        <img :src="url" class="image">
    </div>
    

    注意:

    • 您应该使用等于或短于active 属性更新时间间隔的转换持续时间。在您的原始代码中,幻灯片每 3 秒循环一次,但过渡持续时间设置为 4 秒,导致过渡非常混乱
    • 如果您想要交叉淡入淡出动画,解决方案会更加复杂。

    这是一个概念验证示例:

    Vue.component('Slide', {
      template: `
    	<div>
    		<img :src="url" class="image">
    	</div>`,
      props: ['url']
    });
    
    Vue.component('component-2', {
      template: `<div>
                        <p>component 2</p>
                     </div>`
    });
    
    new Vue({
      el: '#example',
      template: `
      <div class="carousel-wrapper" id="promotions">
    		<transition name="component-fade" mode="out-in">
    			<Slide class="slide" :url="imageUrl" :key="active">
    			</Slide>
    		</transition>
      </div>`,
      data() {
        return {
          list: [{
              url: 'https://static.pexels.com/photos/572741/pexels-photo-572741.jpeg'
            },
            {
              url: 'https://static.pexels.com/photos/575739/pexels-photo-575739.jpeg'
            },
            {
              url: 'https://static.pexels.com/photos/576832/pexels-photo-576832.jpeg'
            }
          ],
          active: 0
        }
      },
      computed: {
        numberOfSlides() {
          return this.list.length - 1
        },
        imageUrl() {
          return this.list[this.active].url;
        }
      },
      created() {
        this.rotate()
      },
      methods: {
        moveSlide(event) {
          this.active = event.srcElement.dataset.slide
          this.list.forEach(el => {
            el.active = false
          })
          this.list[event.srcElement.dataset.slide].active = true
        },
        rotate() {
          if (this.active < this.numberOfSlides) {
            this.active = this.active + 1
          } else {
            this.active = 0
          }
          let _this = this
          setTimeout(_this.rotate, 3000)
        }
      }
    });
    .carousel-wrapper {
      width: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      height: 100%;
    }
    
    .carousel {}
    
    .dots {
      max-width: 100%;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
      position: absolute;
      bottom: 2em;
      z-index: 1;
    }
    
    .dot {
      height: 1em;
      width: 1em;
      margin: 0 1em 0 1em;
      border-radius: 50%;
      background-color: red;
    }
    
    .component-fade-enter-active,
    .component-fade-leave-active {
      transition: opacity 1s ease;
    }
    
    .component-fade-enter,
    .component-fade-leave-to {
      opacity: 0;
    }
    
    .slide {
      width: 100%;
      height: 650px;
    }
    
    .image {
      max-width: 100%;
      max-height: 650px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
    <div id="example">
    </div>

    【讨论】:

      【解决方案2】:

      我认为这是因为您不需要使用v-show

      您应该只使用&lt;transition name="slide-fade"&gt;&lt;slides&gt;&lt;/slides&gt;&lt;/transition&gt;,然后在 CSS 中定义您的过渡。

      你应该看到这个doc,它对我有用。

      【讨论】:

        猜你喜欢
        • 2019-08-15
        • 1970-01-01
        • 1970-01-01
        • 2015-05-28
        • 2012-04-18
        • 2016-09-22
        • 1970-01-01
        • 2017-08-07
        • 1970-01-01
        相关资源
        最近更新 更多