Vue.js 过渡和过渡组动画不起作用

Posted

技术标签:

【中文标题】Vue.js 过渡和过渡组动画不起作用【英文标题】:Vue.js transition and transition-group animations not working 【发布时间】: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

【问题讨论】:

【参考方案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,它对我有用。

【讨论】:

以上是关于Vue.js 过渡和过渡组动画不起作用的主要内容,如果未能解决你的问题,请参考以下文章

iOS中动画组、过渡动画

Android过渡动画不起作用

UIViewController 默认过渡动画不起作用

角度 6 动画 *ngIf,过渡不起作用

如何动画视图插入/删除的过渡?插入动画不起作用

SwiftUI - 过渡动画在 GeoReader 中不起作用?