过渡动画

179 阅读3分钟

Vue 提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画:

Transition 会在一个元素或组件进入和离开 DOM 时应用动画。

TransitionGroup 会在一个 v-for 列表中的元素或组件被插入,移动,或移除时应用动画。

Transition

1. Transition 组件不带 name 属性,默认使用 v- 开头

<button @click="isShow1 = !isShow1">动画1</button>
<!-- 没有设置name属性,样式中使用默认的 v 开头 -->
<Transition>
  <h2 v-if="isShow1">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈11111</h2>
</Transition>
  
  // 在css中定义动画样式
.v-enter-active,
.v-leave-active {
  transition: opacity 1s ease;
}

2. Transition 组件中设置了 name 属性,样式以 name值- 开头

  <button @click="isShow2 = !isShow2">动画2</button>
  <!-- 设置name属性,样式中使用设置的 name值 开头 -->
  <Transition name="cxm">
    <h2 v-if="isShow2">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈22222</h2>
  </Transition>
  
  /* 动画2样式 */
.cxm-enter-active,
.cxm-leave-active {
  transition: opacity 1s ease;
}  

3. 使用@keykeyframes 动画

  <!-- 使用@keykeyframes 动画 -->
  <button @click="isShow3 = !isShow3">动画3</button>
  <Transition name="cxm3">
    <h2 v-if="isShow3">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈33333</h2>
  </Transition>
  
  /* 动画3样式 */
.cxm3-enter-active {
  animation: dh 1s ease;
}
.cxm3-leave-active {
  animation: dh 1s ease reverse;
}
@keyframes dh {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}

4. 使用第三方动画库animate.css

  <!-- 使用第三方库 animate.css动画库 -->
  <button @click="isShow4 = !isShow4">动画4</button>
  <Transition
    enter-active-class="animate__animated animate__backInLeft"
    leave-active-class="animate__animated animate__backOutLeft"
  >
    <h2 v-if="isShow4">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈44444</h2>
  </Transition>
  
  // 在script中引入第三方库
  import "animate.css";

5. 过渡模式 mode

  • 【注】过渡模式中:“多个组件或者元素” 同一时间只能有一个显示/创建
<template>
  <!-- 过渡模式 mode -->
  <button @click="isShow5 = !isShow5">过渡模式</button>
  <Transition name="cxm3" mode="out-in">
    <!-- 
        “多个组件或者元素”  同一时间只能有一个显示/创建
        out-in : 先显示/创建 离开的元素,再显示/创建 进入的元素(先出后进)
        in-out : 先显示/创建 进入的元素,再显示/创建 离开的元素(先进后出)
    -->
    <h2 v-if="isShow5">111111111111111111111111</h2>
    <p v-else>22222222222222222222222222222</p>
  </Transition>
</template>
<script>
import "animate.css";
export default {
  data() {
    return {
      isShow5: true,
    };
  },
};
</script>

<style>
/* 动画3样式 */
.cxm3-enter-active {
  animation: dh 1s ease;
}
.cxm3-leave-active {
  animation: dh 1s ease reverse;
}
@keyframes dh {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}
</style>

TransitionGroup 列表过渡

  • v-enter-active:进入过渡生效时的状态
  • v-leave-active:离开过渡生效时的状态
  • tag:转变为对应的标签
  • name:过渡的名字
<template>
  <input type="text" v-model="mytext" />
  <button @click="handleClick()">add</button>
  <!-- <ul> -->
  <TransitionGroup name="cxm" tag="ul">
    <li v-for="(item, index) in list" :key="item">
      {{ item }}--{{ index }}
      <button @click="handleDel(index)">del</button>
    </li>
  </TransitionGroup>
  <!-- </ul> -->
</template>

<script>
export default {
  data() {
    return {
      mytext: "",
      list: ["111", "222", "333"],
    };
  },
  methods: {
    handleClick() {
      this.list.push(this.mytext);
      //清空输入框,value绑定mytext
      this.mytext = "";
    },

    //删除
    handleDel(index) {
      console.log("del", index);
      //删除第几个???
      this.list.splice(index, 1);
    },
  },
};
</script>

<style>
.cxm-enter-active {
  animation: dh 1s ease;
}
.cxm-leave-active {
  animation: dh 1s ease reverse;
}
@keyframes dh {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}

.cxm-move /* 对移动中的元素应用的过渡 */ {
  transition: all 1s ease;
}

/* 确保将离开的元素从布局流中删除
  以便能够正确地计算移动的动画。 */
.cxm-leave-active {
  position: absolute;
}
</style>

封装组件 - 可复用动画

App.vue

<template>
  <button @click="isShow = !isShow">切换</button>
  <MyTransition>
    <h2 v-if="isShow">红红火火恍恍惚惚哈哈哈哈哈哈哈哈</h2>
  </MyTransition>
</template>

<script>
import MyTransition from "./MyTransition.vue";
export default {
  components: {
    MyTransition,
  },
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

动画组件

<template>
  <Transition name="cxm">
    <slot></slot>
  </Transition>
</template>

<script>
export default {};
</script>

<style>
.cxm-enter-active {
  animation: dh 1s ease;
}
.cxm-leave-active {
  animation: dh 1s ease reverse;
}
@keyframes dh {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}
</style>