CSS 过渡

CSS transition 是实现 Vue 过渡效果最常用的方式。它简单易用,性能优秀,适合大多数场景。

transition 属性

CSS transition 包含四个子属性:

.transition {
  transition-property: all;
  transition-duration: 0.3s;
  transition-timing-function: ease;
  transition-delay: 0s;
}

.transition {
  transition: all 0.3s ease 0s;
}

淡入淡出

最基础也是最常用的过渡效果:

<div id="app">
  <button @click="show = !show">切换</button>
  
  <transition name="fade">
    <div v-if="show" class="box">内容</div>
  </transition>
</div>

<style>
.box {
  width: 200px;
  height: 100px;
  background: #42b983;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

.fade-enter, .fade-leave-to {
  opacity: 0;
}

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

<script>
new Vue({
  el: '#app',
  data: { show: true }
})
</script>

滑动效果

元素从某个方向滑入:

.slide-left-enter, .slide-left-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}

.slide-left-enter-active, .slide-left-leave-active {
  transition: all 0.3s ease;
}

.slide-right-enter, .slide-right-leave-to {
  transform: translateX(100%);
  opacity: 0;
}

.slide-right-enter-active, .slide-right-leave-active {
  transition: all 0.3s ease;
}

.slide-up-enter, .slide-up-leave-to {
  transform: translateY(20px);
  opacity: 0;
}

.slide-up-enter-active, .slide-up-leave-active {
  transition: all 0.3s ease;
}

缩放效果

元素从小到大或从大到小:

.zoom-enter, .zoom-leave-to {
  transform: scale(0.5);
  opacity: 0;
}

.zoom-enter-active, .zoom-leave-active {
  transition: all 0.3s ease;
}

.zoom-big-enter, .zoom-big-leave-to {
  transform: scale(1.5);
  opacity: 0;
}

旋转效果

结合旋转创造动感:

.rotate-enter, .rotate-leave-to {
  transform: rotate(-90deg) scale(0.5);
  opacity: 0;
}

.rotate-enter-active, .rotate-leave-active {
  transition: all 0.4s ease;
}

组合效果

多个变换组合使用:

.combo-enter, .combo-leave-to {
  opacity: 0;
  transform: translateY(30px) scale(0.9);
}

.combo-enter-active, .combo-leave-active {
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

弹性效果

使用 cubic-bezier 创建弹性:

.bounce-enter, .bounce-leave-to {
  transform: scale(0);
  opacity: 0;
}

.bounce-enter-active {
  transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.bounce-leave-active {
  transition: all 0.3s ease;
}

模态框过渡

实际应用示例:

<div id="app">
  <button @click="showModal = true">打开模态框</button>
  
  <transition name="modal">
    <div v-if="showModal" class="modal-overlay" @click="showModal = false">
      <div class="modal-content" @click.stop>
        <h2>模态框标题</h2>
        <p>这是模态框内容</p>
        <button @click="showModal = false">关闭</button>
      </div>
    </div>
  </transition>
</div>

<style>
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-content {
  background: white;
  padding: 20px;
  border-radius: 8px;
  max-width: 500px;
}

.modal-enter, .modal-leave-to {
  opacity: 0;
}

.modal-enter .modal-content,
.modal-leave-to .modal-content {
  transform: scale(0.9) translateY(-20px);
}

.modal-enter-active, .modal-leave-active {
  transition: opacity 0.3s ease;
}

.modal-enter-active .modal-content,
.modal-leave-active .modal-content {
  transition: transform 0.3s ease;
}
</style>

侧边栏过渡

.sidebar-enter, .sidebar-leave-to {
  transform: translateX(-100%);
}

.sidebar-enter-active, .sidebar-leave-active {
  transition: transform 0.3s ease;
}

.sidebar-backdrop-enter, .sidebar-backdrop-leave-to {
  opacity: 0;
}

.sidebar-backdrop-enter-active, .sidebar-backdrop-leave-active {
  transition: opacity 0.3s;
}

卡片翻转

3D 翻转效果:

.flip-enter {
  transform: rotateY(90deg);
}

.flip-enter-active {
  transition: transform 0.5s;
}

.flip-leave {
  transform: rotateY(0);
}

.flip-leave-active {
  transition: transform 0.5s;
}

.flip-leave-to {
  transform: rotateY(-90deg);
}

过渡时间函数

不同的 timing function 创造不同感觉:

.ease { transition-timing-function: ease; }
.linear { transition-timing-function: linear; }
.ease-in { transition-timing-function: ease-in; }
.ease-out { transition-timing-function: ease-out; }
.ease-in-out { transition-timing-function: ease-in-out; }

.custom { transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); }

性能优化

高性能过渡属性:

只使用 transformopacity,它们不会触发重排:

.good {
  transition: transform 0.3s, opacity 0.3s;
}

.avoid {
  transition: width 0.3s, height 0.3s, margin 0.3s;
}

开启硬件加速:

.accelerated {
  will-change: transform, opacity;
  transform: translateZ(0);
}

实用工具类

定义可复用的过渡类:

.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
.fade-enter, .fade-leave-to { opacity: 0; }

.slide-up-enter-active, .slide-up-leave-active { transition: all 0.3s; }
.slide-up-enter, .slide-up-leave-to { transform: translateY(20px); opacity: 0; }

.zoom-enter-active, .zoom-leave-active { transition: all 0.3s; }
.zoom-enter, .zoom-leave-to { transform: scale(0.95); opacity: 0; }

CSS 过渡是实现 Vue 动画的基础,掌握它就能应对大部分场景。