过渡与动

Vue 提供了 <transition> 组件,让你可以在元素插入、更新或移除时应用过渡效果。这让应用更加生动,用户体验更好。

动画不仅仅是视觉装饰,更是引导用户注意力、传达状态变化的重要手段。一个恰到好处的过渡动画,能让界面显得更加流畅自然。

Vue 的过渡系统

Vue 的过渡系统基于 CSS 过渡和动画,通过自动添加和移除 CSS 类名来实现效果:

<transition name="fade">
  <p v-if="show">Hello</p>
</transition>

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

show 变化时,<p> 元素会有淡入淡出效果。

过渡的触发条件

Vue 会在以下情况触发过渡:

  1. 条件渲染v-if
  2. 条件展示v-show
  3. 动态组件<component :is="...">
  4. 根节点:特殊的根元素
<div id="app">
  <transition name="slide">
    <div v-if="show" class="box">内容</div>
  </transition>
  
  <button @click="show = !show">切换</button>
</div>

过渡类名

Vue 在过渡过程中会自动添加 6 个类名:

进入过渡:
v-enter        → 进入开始状态
v-enter-active → 进入过程(定义过渡时间)
v-enter-to     → 进入结束状态

离开过渡:
v-leave        → 离开开始状态
v-leave-active → 离开过程(定义过渡时间)
v-leave-to     → 离开结束状态

如果设置了 name="fade",类名会变成 fade-enterfade-leave 等。

本章内容

  • 过渡类名:深入理解 6 个过渡类名的含义和用法
  • CSS 过渡:使用 CSS transition 属性实现平滑过渡
  • CSS 动画:使用 CSS @keyframes 实现复杂动画
  • 动画库集成:集成 Animate.css 等第三方动画库
  • 列表过渡:使用 <transition-group> 处理列表动画

过渡模式

当两个元素切换时,可能会出现同时存在的问题:

<transition name="fade" mode="out-in">
  <button v-if="isEditing" key="save">保存</button>
  <button v-else key="edit">编辑</button>
</transition>

mode="out-in" 确保先离开再进入,避免重叠。

JavaScript 钩子

除了 CSS,还可以用 JavaScript 控制过渡:

<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
>
  <div v-if="show">内容</div>
</transition>

<script>
new Vue({
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0
    },
    enter(el, done) {
      Velocity(el, { opacity: 1 }, { duration: 500, complete: done })
    },
    afterEnter(el) {
      console.log('进入完成')
    }
  }
})
</script>

初始渲染过渡

如果想在初始渲染时就应用过渡,使用 appear 属性:

<transition appear name="fade">
  <h1>标题</h1>
</transition>

动画性能建议

提升动画性能的技巧:

  1. 使用 transform 和 opacity:这两个属性不会触发重排,性能最好
  2. 避免动画 width/height:会触发重排,性能较差
  3. 使用 will-change:提前告知浏览器即将变化
  4. 合理使用硬件加速transform: translateZ(0)
.good-animation {
  transition: transform 0.3s, opacity 0.3s;
}

.bad-animation {
  transition: width 0.3s, height 0.3s;
}

学习建议

  1. 从简单的淡入淡出开始,逐步尝试更复杂的效果
  2. 多观察优秀应用的动画设计,培养动画感
  3. 注意动画时长,太长会让用户等待,太短可能被忽略
  4. 提供跳过动画的选项,照顾不喜欢动画的用户