Vue3组件过渡动画

1,978 阅读2分钟

transition单组件过渡

transition 标签能够让内部单个组件切换的时候,拥有自定义的动画效果。

transition 拥有自己的属性

  • name:自定义的名称,用于替换 v-enter-from等状态类的 v,在组件切换时,能给组件在不同的时期添加上对应的类
  • 组件的切换动态周期: 周期可以绑定不同的函数
      <!-- 生命周期钩子函数 -->
      <transition @before-enter="beforeEnter"
                  @enter="enter"
                  @after-enter="afterEnter"
                  @before-leave="beforeLeave"
                  @leave="leave"
                  @after-leave="afterLeave">
    
  • duration:延迟时间;设置该属性能够让定义的CSS类中的延迟时间失效,改为设定的时间
  • appear:该属性组件初始化时就执行一次过渡
  • mode:模式,能够让组件过渡更加流畅(out-in: 等上一个组件消失再切换到新的组件)
  • css:给css赋值为false,能够让设置的 v-enter等过渡类失效
  • enter-active-class,leave-active-class: 能够直接给对应的状态加上指定类名

transition的基本使用

更多示例

示例: 实现两个标签的动态切换

注意: vue 通过监听 transition 或 animation 任一结束时选择移入或移除;同时存在时,如果时间不同,可能会产生误差 ,避免动画和过渡同时使用

<template>
  <div>
    <button @click="isShow = !isShow;">显示/隐藏</button>
    <!-- 指定时间的时候,css中写的无效,参考标签的时间 -->
    <!-- 没有设置mode的时候,二者切换时的动画是同时执行的 -->
    <!-- 设置mode为先出后入,则是先隐藏元素再显示新元素 -->
    <!-- appear属性存在,表示初始化时也显示动画效果 -->
    <transition name="code" :duration="1000" mode="out-in" appear>
      <!-- 使用组件也是如此, component组件进行动态切换 -->
      <h2 v-if="isShow">Hello World</h2>
      <h2 v-else>transition mode</h2>
    </transition>
  </div>
</template><script>
export default {
  data() {
    return {
      isShow: false,
    };
  },
};
</script><style scoped>
/* 
  enter 对应的是元素插入
  leave 对应是元素移除
  code 是transition组件对应的name属性
*/
/* .code-enter-from,
.code-leave-to {
  opacity: 0;
}
​
.code-enter-to,
.code-leave-from{
  opacity: 1;
}
​
.code-enter-active,
.code-leave-active {
  transition: opacity 1s ease;
} *//* 不仅可以使用过渡,还可以使用animation动画效果 */
.code-enter-active {
  animation: bounce 1s ease;
}
.code-leave-active {
  animation: bounce 1s ease reverse;
}
@keyframes bounce {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}

transition-group多组件过渡

transition-group 标签,让内部多个组件实现过渡;同时该组件拥有和transition同样的属性 attribute

transition-group的使用

更多示例

示例: 实现数组添加移除动画

<template>
  <div>
    <div>
      <button @click="addNum">添加数字</button>
      <button @click="removeNum">删除数字</button>
      <button @click="lodashNum">数组洗牌</button>
    </div>
    <transition-group name="code">
      <span v-for="item in numbers" :key="item">
        {{ item }}
      </span>
    </transition-group>
  </div>
</template><script>
// 第三方库,能够打乱数组的排序(需要自行下载)
// npm install lodash
import _  from "lodash";
export default {
  data() {
    return {
      numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8],
      count: 9,
    };
  },
  methods: {
    addNum() {
      this.numbers.splice(this.randomIndex(), 0, this.count++);
    },
    removeNum() {
      this.numbers.splice(this.randomIndex(), 1);
    },
    lodashNum(){
      // 重排
      this.numbers = _.shuffle(this.numbers)
    },
    randomIndex() {
      return Math.floor(Math.random() * this.numbers.length - 1 );
    },
  },
};
</script><style scoped>
span {
  display: inline-block;
  margin: 5px;
  font-weight: 600;
}
​
.code-enter-active {
  animation: flash 0.5s ease;
}
​
.code-leave-active {
  animation: flash 0.5s ease  reverse;
  /* 移除的时候添加该属性,能够修复动画不出现的效果 */
  position: absolute;
}
​
@keyframes flash {
  from {
    opacity: 0;
    transform: translateY(50px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
​
/* 移除的时候,原属性会占据位置,导致动画无法出现 */
/* v-move(v匹配name属性),能够添加其他需要移动的节点动画 */
.code-move {
  transition: transform 1s ease;
}
</style>

第三方库实现动画过渡效果

示例代码可以点击链接查看

animate.css 动画库

下载animate.css动画库

 npm install animate.css

在main.js文件中全局导入 css库

  import "animate.css

给对应的标签或组件添加动画时需要带上前缀以及对应动画类名:例如

    <transition
      enter-active-class="animate__animated animate__backOutUp"
      leave-active-class="animate__animated animate__reverse"
    >
      <h2 v-if="isShow">hello world</h2>
      <h2 v-else>animate.css</h2>
    </transition>
.animate__reverse {
  animation-name: animate__backOutUp;
  animation-direction: reverse;
}

gsap js动画库

下载gsap动画库

npm install gsap

使用时,将其引入

import gsap from "gsap";

使用其api,实现指定效果:各项延迟进入或移除

    enter(el, done) {
      // el元素通过dataset属性获取到自定义命名的属性
      // delay延迟执行动画效果
      gsap.to(el, {
        opacity: 1,
        height: "1.5em",
        delay: el.dataset.index * 0.2,
        onComplete: done,
      });
    },
    leave(el, done) {
      gsap.to(el, {
        opacity: 0,
        height: 0,
        delay: el.dataset.index * 0.2,
        onComplete: done,
      });
    },