Skip to content
第 16 章 前端 ⏱ 12 分钟阅读

第 16 章:动画 ​

学习目标 ​

  • 用 <Transition> 包裹单元素
  • 用 <TransitionGroup> 做列表过渡
  • 配合 CSS 类名 / keyframes 实现动画
  • 避坑:display:none 与动画冲突

一、单元素过渡 ​

vue
<template>
  <button @click="show = !show">toggle</button>
  <Transition name="fade">
    <p v-if="show">Hello</p>
  </Transition>
</template>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

类名时序:

  1. v-enter-from 进入前
  2. v-enter-active 进入过程
  3. v-enter-to 进入完成
  4. 离开:v-leave-from → v-leave-active → v-leave-to

⚠️ 坑 1:如果元素上有 display: none,动画不会触发。

二、keyframes 动画 ​

css
.zoom-enter-active {
  animation: zoom 0.3s;
}
.zoom-leave-active {
  animation: zoom 0.3s reverse;
}

@keyframes zoom {
  from { transform: scale(0); }
  to   { transform: scale(1); }
}

三、列表过渡 ​

vue
<TransitionGroup name="list" tag="ul">
  <li v-for="item in items" :key="item.id">{{ item.text }}</li>
</TransitionGroup>
css
.list-enter-active, .list-leave-active {
  transition: all 0.3s;
}
.list-enter-from { opacity: 0; transform: translateX(30px); }
.list-leave-to   { opacity: 0; transform: translateX(-30px); }
.list-move       { transition: transform 0.3s; }

⚠️ 坑 2:列表项必须带 :key,否则 move 动画不生效。

四、JS 钩子 ​

vue
<Transition
  :css="false"
  @before-enter="onBeforeEnter"
  @enter="onEnter"
  @leave="onLeave"
>
  <p v-if="show">Hi</p>
</Transition>
ts
const onEnter = (el: Element, done: () => void) => {
  const animate = (el as HTMLElement).animate(
    [{ opacity: 0 }, { opacity: 1 }],
    { duration: 300 },
  )
  animate.onfinish = done
}

五、appear 首次加载 ​

vue
<Transition name="fade" appear>
  <p>页面打开就出现</p>
</Transition>

六、mode 控制时机 ​

vue
<Transition name="fade" mode="out-in">
  <p v-if="ok">A</p>
  <p v-else>B</p>
</Transition>
mode行为
默认同时进出,会重叠
out-in先走再进
in-out先进再走

七、实战:折叠面板 ​

vue
<template>
  <button @click="open = !open">{{ open ? '收起' : '展开' }}</button>
  <Transition name="collapse">
    <div v-show="open" class="content">
      <slot />
    </div>
  </Transition>
</template>

<style>
.collapse-enter-active, .collapse-leave-active {
  transition: max-height 0.3s, opacity 0.3s;
  overflow: hidden;
}
.collapse-enter-from, .collapse-leave-to {
  max-height: 0;
  opacity: 0;
}
.collapse-enter-to, .collapse-leave-from {
  max-height: 500px;
  opacity: 1;
}
</style>

⚠️ 坑 3:height: auto 不能直接 transition,要用 max-height 撑开。

八、本章小结 ​

类名作用
-enter-from进入前
-enter-active进入过程
-enter-to进入完成
-leave-*离开对应
-move列表移动

动手练习 ​

  1. 淡入淡出:按钮切换显示/隐藏,带过渡
  2. 列表动画:加 / 删 todo,带 move 动画
  3. 折叠面板:用 max-height 实现可展开内容

下一章:第 17 章:过渡 →

本站基于 VitePress 构建 · 由 StackHub 团队维护