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

第 17 章:过渡 ​

学习目标 ​

  • 路由切换动画
  • 列表过渡与状态切换
  • 配合第三方库(GSAP / motion)
  • 性能优化

一、路由过渡 ​

vue
<!-- App.vue -->
<template>
  <router-view v-slot="{ Component, route }">
    <Transition name="page" mode="out-in">
      <component :is="Component" :key="route.fullPath" />
    </Transition>
  </router-view>
</template>

<style>
.page-enter-active, .page-leave-active {
  transition: opacity 0.3s, transform 0.3s;
}
.page-enter-from { opacity: 0; transform: translateY(10px); }
.page-leave-to   { opacity: 0; transform: translateY(-10px); }
</style>

⚠️ 坑 1::key 必须用 route.fullPath,否则同组件切换参数不触发过渡。

二、状态切换过渡 ​

vue
<template>
  <button @click="state = state === 'A' ? 'B' : 'A'">切换</button>
  <Transition name="swap" mode="out-in">
    <p :key="state">{{ state }}</p>
  </Transition>
</template>

三、配合 motion-v(推荐) ​

bash
npm i motion-v
vue
<script setup lang="ts">
import { motion } from 'motion-v'
</script>

<template>
  <motion.div :initial="{ opacity: 0 }" :animate="{ opacity: 1 }" :exit="{ opacity: 0 }">
    内容
  </motion.div>
</template>

四、配合 GSAP ​

ts
import gsap from 'gsap'

const onEnter = (el: Element, done: () => void) => {
  gsap.from(el, { opacity: 0, y: 30, onComplete: done })
}
vue
<Transition :css="false" @enter="onEnter">
  <div v-if="show">Hi</div>
</Transition>

五、列表交错动画 ​

vue
<TransitionGroup
  tag="ul"
  :css="false"
  @enter="onEnter"
  @leave="onLeave"
>
  <li v-for="(item, i) in items" :key="item.id" :data-index="i">
    {{ item.text }}
  </li>
</TransitionGroup>
ts
const onEnter = (el: Element) => {
  const i = +(el as HTMLElement).dataset.index!
  gsap.from(el, { opacity: 0, x: -30, delay: i * 0.05 })
}

六、性能优化 ​

css
/* 优先 transform / opacity,走 GPU */
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s, transform 0.3s;
  will-change: opacity, transform;
}

⚠️ 坑 2:will-change 用多了反而卡,动画结束后移除。

七、JS 钩子完整签名 ​

ts
@before-enter   (el)
@enter          (el, done)         // 主动调用 done
@after-enter    (el)
@enter-cancelled (el)
@before-leave   (el)
@leave          (el, done)
@after-leave    (el)
@leave-cancelled (el)

⚠️ 坑 3:用了 JS 钩子就不要同时写 CSS,会冲突。

八、本章小结 ​

场景方案
路由切换router-view 套 Transition
列表交错GSAP delay
复杂动画motion-v / GSAP
性能transform / opacity 优先

动手练习 ​

  1. 路由淡入:全局加路由过渡
  2. 列表交错:用 GSAP 让列表项依次进入
  3. 状态切换:数字 0 / 1 切换,数字带缩放动画

下一章:第 18 章:样式与 scoped →

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