使用Transition在Vuejs中为v-if设置动画高度

时间:2017-03-04 02:21:07

标签: css animation vuejs2 vue.js

我使用以下代码通过将高度降低到0px来为v-if元素设置动画。动画效果很好。但问题是我要指定元素的初始高度是CSS。对于一个元素,这没关系,但我想将此动画应用于多个元素。我怎样才能解决这个问题?无论高度如何,动画效果都很好!

<transition name="fadeHeight" mode="out-in">
<div v-if="something">
<p>something over here where the height is not constant</p>
</div>
</transition>

.fadeHeight-enter-active,
.fadeHeight-leave-active {
  transition: all 0.2s;
  height: 230px;
}
.fadeHeight-enter,
.fadeHeight-leave-to
{
  opacity: 0;
  height: 0px;
}

2 个答案:

答案 0 :(得分:20)

您似乎没有发布所有代码,但希望我了解目标。

尝试将过渡移动到max-height属性:

.fadeHeight-enter-active,
.fadeHeight-leave-active {
  transition: all 0.2s;
  max-height: 230px;
}
.fadeHeight-enter,
.fadeHeight-leave-to
{
  opacity: 0;
  max-height: 0px;
}

只要您将最大高度设置为大于最高元素,它就应该完成您所需要的。请注意,您可能还想使用overflow:hidden。如果元素的实际高度有显着变化,这个解决方案可能不是最好的,因为它会使动画持续时间/延迟显得非常不同。

https://jsfiddle.net/7ap15qq0/4/

答案 1 :(得分:2)

@ryantdecker 提供了最常见的答案。不过我更喜欢少写代码,而是使用类绑定

<template>
 <!-- isShowing either a data or computed... -->
 <div class="foo" :class="{'showing': isShowing', 'hidden': !isShowing}">
  <p>
   something over here where the height is not constant
  </p>
 </div>
</template>
...
<style>
.foo {
 height: auto;
 transition: max-height 0.5s;
 &.showing {
  max-height: 200px; //MUST BE MORE THAN height:auto
 }
 &.hidden {
  max-height: 0px;
 }
}
</style>

一些可以进行更多控制的自定义是:

  1. 设置:style="{'max-height': computedHeight}"
  2. 分别在 ease-inease-out 类中将 transitions.showing 与两个不同的 .hidden 一起使用。
  3. 对折叠/展开的非常长的内容使用三次贝塞尔过渡速度

当您使用不同的项目时,可以使用上面的第一个自定义,例如图片、可通过 devtools 看到高度和计算高度的 flex 行。例如:

computed: {
 /**
  * @return {string} max height of the container in pixels if shown else zero
  */
 calcedHeight()
 {
   const elHeight = 80;
   const maxHeight = this.isShowing ? elHeight * this.elementCount : 0
   const maxHeightPx = maxHeight + 'px'
   return {
    'max-height': maxHeightPx
   }
 }
}

此时可以很容易地将其制成带有 isShowingelHeightelCount 道具的组件。

三次贝塞尔

我给它自己的部分,因为它可能是关于疯狂的长元素(想想 5000px max-heights)所需的全部内容:

&.showing {                                                                                          
   transition: all 0.6s cubic-bezier(1, 0.01, 1, 0.01);                                                 
}                                                                                                       
&.hidden {                                                                                           
   transition: all 0.6s cubic-bezier(0.01, 1, 0.01, 1);                                                 
}