likes
comments
collection
share

vue-竟然有这么多种实现动画

作者站长头像
站长
· 阅读数 13

前言

平时上网我经常能在app或者网页上看到很多比较酷的动画效果,这些效果还是比较吸引人的。那么我们自己在写项目时,也都希望能在页面做出一些很酷的动画效果,页面看起来也会更具特色。所以我总结了一些在vue的项目开发中,我们能够实现动画效果的方法,希望能够帮助到大家。以下我已经使用快捷方式创建了一个vue项目,再创建不同页面并引用来展示不同的效果

动画的基本实现

通常我们实现动画效果会用到CSS中的class类,这也是比较基本的方式实现动画。先利用@keyframes定义一个动画,再在需要实现该动画的DOM结构中使用animation属性引用该动画。通常我们在animation属性中会使用到四个值,分别是动画名、动画完成需要的时间、动画的效果、动画循环的次数,但其实animation可以设置的值还有很多,这里我们只使用这四种。@keyframes定义整个动画的过程,从开始的 0% 到结束的 100% ,中间也能设置其他过程节点,在这些节点上设置不同的属性效果,从而实现动画。这种方式在平时的html中同样适用。

<template>
  <div class="box"></div>
</template>

<script>
</script>

<style scoped>
  .box{
    width: 50px;
    height: 50px;
    background: rgb(112, 251, 112);
    position: relative;
    animation: move 2s linear infinite;
  }
  @keyframes move{
    0%{
      left:0px;
    }
    50%{
      left:200px;
    }
    100%{
      left: 0px;
    }
  }
</style>

vue-竟然有这么多种实现动画

Vue组件-Transition

<Transition> 是vue的一个内置组件,这意味着它在任意别的组件中都可以直接被使用,无需注册。它可以设置其内部元素进入和离开的动画,主要由 v-ifv-show 触发,也可以由特殊元素 <component> 切换的动态组件,或者改变特殊的key属性来触发,原理就是元素的出现和消失,这里我只以v-if为例。这种方法是由class属性来控制动画的过渡效果,总共有六种用于过渡的class属性(其中 v 指<Transition>里面的name属性)

1.  `v-enter-from`:进入动画的起始状态。在元素插入之前添加,在元素插入完成后的下一帧移除。
2.  `v-enter-active`:进入动画的生效状态。应用于整个进入动画阶段。在元素被插入之前添加,在过渡或动画完成之后移除。这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型。
3.  `v-enter-to`:进入动画的结束状态。在元素插入完成后的下一帧被添加 (也就是 `v-enter-from` 被移除的同时),在过渡或动画完成之后移除。
4.  `v-leave-from`:离开动画的起始状态。在离开过渡效果被触发时立即添加,在一帧后被移除。
5.  `v-leave-active`:离开动画的生效状态。应用于整个离开动画阶段。在离开过渡效果被触发时立即添加,在过渡或动画完成之后移除。这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型。
6.  `v-leave-to`:离开动画的结束状态。在一个离开动画被触发后的下一帧被添加 (也就是 `v-leave-from` 被移除的同时),在过渡或动画完成之后移除。
<template>
  <button @click="toggle">click</button>
  <Transition name="fade" >
    <h1 v-if="showTitle">你好 vue</h1>
  </Transition>
</template>

<script>
import { ref } from 'vue'

export default {
  setup () {
    let showTitle = ref(true)
    const toggle = () =>{
      showTitle.value = !showTitle.value
    }

    return {
      showTitle,
      toggle
    }
  }
}
</script>

<style scoped>
  .fade-enter-active,.fade-leave-active{
    transition: opacity 1s ease;
  }
  .fade-enter-from,.fade-leave-to{
    opacity: 0;
  }
  .fade-enter-to,.fade-leave-from{
    opacity: 1;
  }
  /* 以下部分在上面动画基础上添加缩放动画效果 */
  /* .fade-enter-active{
    animation:bounce 1s ease;
  }
  .fade-leave-active{
    animation:bounce 1s ease reverse;
  }

  @keyframes bounce{
    0%{transform:scale(0);}
    50%{transform:scale(1.2);}
    100%{transform:scale(1);}
  } */
</style>

vue-竟然有这么多种实现动画

vue-竟然有这么多种实现动画

Transition生命周期函数

除了使用class属性控制动画的过渡效果,<Transition>内还可以使用生命周期方法来控制动画效果,也就是对<Transition>绑定其特有的事件,事件触发相应的js函数实现动画效果,同样控制元素进入和离开的动画。总共有六个生命周期函数,它们只能被<Transition>使用

1. @before-enter=" "  //进入前触发
2. @enter=" " //进入期间触发
3. @after-enter=" " //进入后触发
4. @before-leave=" " //离开前触发
5. @leave=" " //离开期间触发
6. @after-leave=" " //离开后触发

(由于js可以设置和控制很多类型的动画,这里没有做详细动画演示,大家可以自己填入设计)

<template>
  <button @click="isShow = !isShow">click</button>
  <Transition 
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  >
    <h1 v-if="isShow">hello vue</h1>
  </Transition>
  
</template>

<script>
import { ref } from 'vue';

export default {
  setup () {
    const isShow = ref(true)

    const beforeEnter = () =>{

    }
    const enter = () =>{
      
    }
    const afterEnter = () =>{
      
    }
    const beforeLeave = () =>{
      
    }
    const leave = () =>{
      
    }
    const afterLeave = () =>{
      
    }
    return {
      isShow,
      beforeEnter,
      enter,
      afterEnter,
      beforeLeave,
      leave,
      afterLeave
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

借助第三方库

通过已经封装好的第三方库,我们可以更加方便的实现自己想要的动画效果,这里为大家推荐两个动画库 animate.cssGSAP

animate.css

Animate.css | A cross-browser library of CSS animations.

这个动画库里已经封装好了很多可以选择的动画效果,它是通过CSS来实现的。通过 npm 或 yarn 安装就可以引入使用,引入也可以通过 import 或 link 引入,比较方便。使用时,只要在需要动画的元素的class类中加入animate__animated 和相应动画的类名就可以实现动画,也可以配合<Transition>等使用,达到自己想要的效果。这里配合<Transition>,直接设置enter-active-class 和 leave-active-class 属性类名,分别表示进入动画和离开动画。

<template>
  <button @click="isShow = !isShow">click</button>
  <Transition
   enter-active-class="animate__animated animate__bounceInDown"
   leave-active-class="animate__animated animate__bounce">
    <h1 v-if="isShow">hello vue</h1>
  </Transition>
</template>

<script>
import { ref } from 'vue';

export default {
  setup () {
    const isShow = ref(true)

    return {
      isShow
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

vue-竟然有这么多种实现动画

GSAP

GSAP 中文教程 中文文档 |官方文档 官方教程翻译 |好奇代码出品

和 animate.css 不同,GSAP 是通过js来实现动画的,好处就是一些想到的动画效果是css很难实现的,而js就能更加好地完成。可以通过 npm 安装,也可以直接 CDN 引入,这样就可以在我们的项目中使用这些动画了。这里我们讲里面的 tween 动画类型,也叫补间动画,就是我们常见的两个状态之间的变化的动画方式,比如我们常见的匀速、缓入缓出动画就是Tween类型的动画。总共有四种Tween的动画方式:

  • gsap.to(): 这是一种最常用的tween动画,就是让元素从初始状态变化到目标状态。

  • gsap.from(): 有点像to方法的逆向变化,就是让元素从目标状态变化到初始状态。

  • gsap.fromTo(): 需要自己定义两个状态的数据,然后从前一个变化到后一个。

  • gsap.set():直接设置成想要的状态,没有任何过度与动画效果。本质上就是duration为0的 .to 方法

假如我们创建一个动画,代码为:gsap.to(".box", { x: 200 }),其中的两个参数分别表示目标和对象参数,意思是把带有'.box'类名的元素移动到x为200的位置”(就像transform: translateX(200px))。我们这里配合<Transition>的生命周期函数完成一个动画:

<template>
  <button @click="isShow = !isShow">click</button>
  <Transition @enter="enter" @leave="leave">
    <h1 v-if="isShow">hello vue</h1>
  </Transition>
</template>

<script>
import { ref } from 'vue';
import gsap from 'gsap'

export default {
  setup () {
    const isShow = ref(true)
    const enter = (el,done) =>{
      gsap.from(el,{ //el表示目标dom结构,即元素
        scale:0, //缩放到0
        x:200, // x方向移动200px
        onComplete:done //参数done是一个函数,若传入了该参数,就必须调用,表示动画完成,否者看不到动画效果
      })
    }
    const leave = (el,done)=>{
      gsap.to(el,{
        scale:0,
        x:200,
        onComplete:done
      })
    }
    return {
      isShow,
      enter,
      leave
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

vue-竟然有这么多种实现动画

再制作一个数字变化加载的动画效果:

<template>
  <input type="number" step="100" v-model="counter">
  <h1>{{ showNumber }}</h1>
</template>

<script>
import { toRefs, watch, reactive } from 'vue';
import gsap from 'gsap'

export default {
  setup () {
    
    const state = reactive({
      counter:0,
      showNumber:0
    })

    watch( //监听变量的值的变化
      () => state.counter,
      (newVal) =>{
        gsap.to(state,{duration:1,showNumber:newVal}) //duration的值控制动画的事件
      }
    )

    return {
      ...toRefs(state)
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

vue-竟然有这么多种实现动画

Transition-group

<transition>中只能包裹一个元素,当出现需要多个元素时,可以使用<Transition-group>,下面也简单制作了一个多元素,数据变化的一个动画:

<template>
  <div>
    <button @click="addNum">add</button>
    <button @click="removeNum">remove</button>
    <button @click="shuffleNum">shuffle</button>

  </div>
  <transition-group name="fade">
    <span v-for="item in numbers" :key="item">{{ item }}</span>
  </transition-group>
</template>

<script setup>
import { ref } from 'vue';
import _ from 'lodash' //先npm安装,再引用

const numbers = ref([0,1,2,3,4,5,6,7,8])
const count = ref(10)
const addNum = ()=>{ //在随机位置添加 count
  numbers.value.splice(randomIndex(),0,count.value++)
}

const removeNum = () => { //删除随机一个位置的数
  numbers.value.splice(randomIndex(),1)
}

const shuffleNum = () => { //借助lodash库,已经封装的打乱数组的方法
  numbers.value = _.shuffle(numbers.value)
}

const randomIndex = () =>{ //随机数方法
  return Math.floor(Math.random()*numbers.value.length)
}
</script>

<style scoped>
  span{
    margin-right: 10px;
    display: inline-block;
  }
  .fade-enter-from,.fade-leave-to{
    opacity: 0;
    transform: translateY(30px);
  }
  .fade-enter-active,.fade-leave-active{
    transition:all 1s ease
  }
  .fade-leave-active {
    position: absolute;
  }
  /*移动时的动画效果*/
  .fade-move { 
    transition:transform 1s ease;
  }
</style>

vue-竟然有这么多种实现动画

总结

制作动画的方法有很多,很多生动的动画效果才能引用人的眼球,希望以上动画的实现方法能够帮助到大家,结合自己的想象,也可以制作更多炫酷的效果。

转载自:https://juejin.cn/post/7265968558009417788
评论
请登录