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

前言

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

动画的基本实现

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

xml 复制代码
<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组件-Transition

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

markdown 复制代码
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` 被移除的同时),在过渡或动画完成之后移除。
xml 复制代码
<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>

Transition生命周期函数

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

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

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

ini 复制代码
<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 属性类名,分别表示进入动画和离开动画。

xml 复制代码
<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>

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>的生命周期函数完成一个动画:

xml 复制代码
<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>

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

xml 复制代码
<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>

Transition-group

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

xml 复制代码
<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>

总结

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

相关推荐
Larcher19 分钟前
新手也能学会,100行代码玩AI LOGO
前端·llm·html
徐子颐32 分钟前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
小月鸭44 分钟前
如何理解HTML语义化
前端·html
jump6801 小时前
url输入到网页展示会发生什么?
前端
诸葛韩信1 小时前
我们需要了解的Web Workers
前端
brzhang1 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu2 小时前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花2 小时前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js
十二春秋2 小时前
场景模拟:基础路由配置
前端
六月的可乐2 小时前
实战干货-Vue实现AI聊天助手全流程解析
前端·vue.js·ai编程