TransitionGroup·过渡组 {#transitiongroup}

<TransitionGroup> 是一个内置组件,设计用于呈现一个列表中的元素或组件的插入、移除和顺序改变的动画效果。

<Transition> 的区别 {#differences-from-transition}

<TransitionGroup> 支持和 <Transition> 基本相同的 prop、CSS 过渡 class 和 JavaScript 钩子监听器,但有以下几点区别:

  • 默认情况下,它不会渲染一个包装器元素。但你可以通过传入 tag prop 来指定一个元素作为包装器元素来渲染。

  • 过渡模式在这里不可用,因为我们不再是在互斥的元素之间进行切换。

  • 其中的元素总是必须有一个独一无二的 key attribute。

  • CSS 过渡 class 会被应用在其中的每一个元素上,而不是这个组的容器上。

:::tip 当你是在 DOM 模板中使用时,组件名需要写为 <transition-group>。 :::

进入 / 离开过渡 {#enter-leave-transitions}

这里是 <TransitionGroup> 对一个 v-for 列表应用进入 / 离开过渡的示例:

  1. <TransitionGroup name="list" tag="ul">
  2. <li v-for="item in items" :key="item">
  3. {{ item }}
  4. </li>
  5. </TransitionGroup>
  1. .list-enter-active,
  2. .list-leave-active {
  3. transition: all 0.5s ease;
  4. }
  5. .list-enter-from,
  6. .list-leave-to {
  7. opacity: 0;
  8. transform: translateX(30px);
  9. }

移动过渡 {#move-transitions}

上面的示例有一些明显的缺陷:当某一项被插入或移除时,它周围的元素会立即发生“跳跃”而不是平稳地移动。我们可以通过添加一些额外的 CSS 规则来解决这个问题:

  1. .list-move, /* 对移动中的元素应用的过渡 */
  2. .list-enter-active,
  3. .list-leave-active {
  4. transition: all 0.5s ease;
  5. }
  6. .list-enter-from,
  7. .list-leave-to {
  8. opacity: 0;
  9. transform: translateX(30px);
  10. }
  11. /* 确保将离开的元素从布局流中删除
  12. 以便能够正确地计算移动的动画。 */
  13. .list-leave-active {
  14. position: absolute;
  15. }

现在它看起来好多了,甚至对整个列表执行洗牌的动画也都非常流畅:

完整的示例

交错的列表过渡 {#staggering-list-transitions}

如果通过 data attribute 用 JavaScript 来执行过渡时,那么我们也可以实现列表中的交错过渡。首先,我们把某一项的索引作为 DOM 元素上的一个 data attribute 呈现出来。

  1. <TransitionGroup
  2. tag="ul"
  3. :css="false"
  4. @before-enter="onBeforeEnter"
  5. @enter="onEnter"
  6. @leave="onLeave"
  7. >
  8. <li
  9. v-for="(item, index) in computedList"
  10. :key="item.msg"
  11. :data-index="index"
  12. >
  13. {{ item.msg }}
  14. </li>
  15. </TransitionGroup>

接着,在 JavaScript 钩子中,我们基于这个 data attribute 对该元素执行一个延迟动画:

  1. function onEnter(el, done) {
  2. gsap.to(el, {
  3. opacity: 1,
  4. height: '1.6em',
  5. delay: el.dataset.index * 0.15,
  6. onComplete: done
  7. })
  8. }

相关内容