当前位置: 首页 > article >正文

《Vue3 七》Vue 中的动画

Vue 提供了一些内置组件和对应的 API 来完成动画,利用它们可以方便地实现动画效果。

<transition> 内置组件:

Vue 提供了 <transition> 内置组件,可以给任意元素或组件添加进入/离开时的动画效果。在条件渲染、动态组件、改变 key 属性时将会触发。

主要针对单个元素或组件。

transition 过渡动画:

<!-- 给 <div> 元素的显示与隐藏添加过渡动画 -->
<template>
  <!-- 2. 使用 <transition> 包裹想要添加动画的元素,Vue 在恰当的时机将编写好的类自动添加、移除  -->
  <transition>
    <div v-if="isShow">Hello Vue</div>
  </transition>
  <button @click="handleChange">切换</button>
</template>

<script setup>
import {ref} from 'vue'
const isShow = ref(false)
const handleChange = () => {
  isShow.value = !isShow.value
}
</script>

<style scoped>
/* 1. 编写想要的动画的类 */
/* 进入前的状态 */
.v-enter-from, 
/* 离开后的状态 */
.v-leave-to {
  opacity: 0;
}

/* 进入后的状态  */
.v-enter-to,
/* 离开前的状态 */
.v-leave-from {
  opacity: 1;
}

/* 进入时的效果 */
.v-enter-active,
/* 离开时的效果 */
.v-leave-active {
  transition: opacity 1s ease;
}
</style>  

在这里插入图片描述

animation 序列帧动画:

<!-- 给 <div> 元素的显示与隐藏添加 animation 动画 -->
<template>
  <!-- 2. 使用 <transition> 包裹想要添加动画的元素,Vue 在恰当的时机将编写好的类自动添加、移除  -->
  <transition>
    <div v-if="isShow">Hello Vue</div>
  </transition>
  <button @click="handleChange">切换</button>
</template>

<script setup>
import {ref} from 'vue'
const isShow = ref(false)
const handleChange = () => {
  isShow.value = !isShow.value
}
</script>

<style scoped>
/* 1. 编写想要的动画的类 */
@keyframes enterAnimation {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(2);
  }
  100% {
    transform: scale(1);
  }
}

/* 进入时的效果 */
.v-enter-active {
  animation: enterAnimation 1s ease;
}

@keyframes leaveAnimation {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(2);
  }
  100% {
    transform: scale(0);
  }
}

/* 离开时的效果 */
.v-leave-active {
  animation: leaveAnimation 1s ease;
}
</style>  

<transition> 组件的原理:

Vue 并没有编写好动画的类,只是会在恰当的时机将开发者编写好的类自动添加、移除。

当插入或者删除包含在 <transition> 组件中的元素时,Vue 会做以下处理:

  1. 自动嗅探目标元素是否应用了 CSS 动画,如果有的话,那么将会在恰当的时机自动添加/移除 CSS 类名。
  2. 如果 <transition> 组件提供了 JavaScript 钩子函数,那么这些钩子函数将会在恰当的时机被调用。
  3. 如果没有检测到 CSS 动画并且也没有找到 JavaScript 钩子函数,那么 DOM 的插入、删除操作将会立即执行。

<transition> 组件的属性:

  1. name:动画的 class 类名的前缀。
  2. duration:显式地设置动画的持续时间。
  3. appear:首次渲染时是否采用动画。默认首次渲染是没有动画的。
  4. type:当同时使用过渡动画和序列帧动画时,以谁的时间为动画的结束时刻。属性值可以为 transition 或者 animation。当不设置type时,默认会取 transitioned 和 animationed 两者更长的为结束时刻。
  5. mode:当一个动画在两个元素之间切换时,如果不希望同时执行进入动画和离开动画,俺么可以设置动画的过渡模式。属性值可以为 in-out,新元素先过渡进入,完成之后当前元素再过渡离开;out-in:当前元素先过渡离开,新元素再过渡进入。
      <template>
        <!-- 如果不设置 mode 过渡属性,那么一个元素显示、一个元素消失将会同时执行动画。设置 mode="out-in" 之后,Hello Vue 会先消失,然后你好,世界再显示 -->
        <transition mode="out-in">
          <div v-if="isShow">Hello Vue</div>
          <div v-else> 你好,世界</div>
        </transition>
        <button @click="handleChange">切换</button>
      </template>
      
      <script setup>
      import {ref} from 'vue'
      const isShow = ref(true)
      const handleChange = () => {
        isShow.value = !isShow.value
      }
      </script>
      
      <style scoped>
      .v-enter-from, 
      .v-leave-to {
        opacity: 0;
      }
      
      .v-enter-to,
      .v-leave-from {
        opacity: 1;
      }
      
      .v-enter-active,
      .v-leave-active {
        transition: opacity 1s ease;
      }
      </style>  
    

动画的 class 类:

  1. v-enter-from:进入动画的起始状态。在元素被插入之前添加,在元素插入完成后的下一帧移除。
  2. v-enter-active:进入动画的生效状态。应用于整个进入动画阶段,在元素被插入之前添加,在动画完成之后移除。
  3. v-enter-to:进入动画的结束状态。在元素被插入完成后的下一帧添加,在动画完成之后移除。
  4. v-leave-from:离开动画的起始状态。在离开动画被触发时立刻添加,下一帧被移除。
  5. v-leave-active:离开动画的生效状态。应用于整个离开动画阶段,在离开动画被触发时立刻添加,在动画完成之后移除。
  6. v-leave-to:离开动画的结束状态。在离开动画被触发后的下一帧添加,在动画完成之后移除。

动画的 class 类的命名规则:

  1. 如果使用的是一个没有 name 的 <transition> ,那么所有的 class 是以 v- 作为默认前缀。
  2. 如果给 <transition> 添加了 name 属性,那么所有的 class 会以 name 属性值做前缀。例如 <transition name=''fade>,那么所有的 class 以 fase- 为前缀。

<transition-group> 内置组件:

Vue 提供了 <transition-group> 内置组件,可以为列表添加、删除数据时添加动画效果。

主要针对列表元素或组件。

<!-- 列表添加、删除元素时,添加、删除的元素将会运用动态效果 -->
  <template>
    <!-- 默认情况下,<transition-group> 不会渲染成一个元素的包裹器,可以通过指定 tag 属性将其渲染为想要的元素 -->
    <transition-group tag="div">
      <!-- 内部元素总是需要提供唯一的 key 属性。CSS 动画的类将会应用在内部的元素上,而不是外面的包裹容器上 -->
      <template v-for="item in nums" :key="item">
        <div>{{ item }}</div>
      </template>
    </transition-group>
    <button @click="handleAdd">插入</button>
    <button @click="handlDelete">删除</button>
  </template>
  
  <script setup>
  import {ref} from 'vue'
  const nums = ref([0, 1, 2, 3, 4, 5])
  const randomIndex = () => {
    return Math.floor(Math.random() * nums.value.length)
  }
  const handleAdd = () => {
    nums.value.splice(randomIndex(), 0, nums.value.length)
  }
  const handlDelete = () => {
    nums.value.splice(randomIndex(), 1)
  }
  </script>
  
  <style scoped>
  .v-enter-from, 
  .v-leave-to {
    opacity: 0;
     transform: translateY(30px);
  }
  
  .v-enter-to,
  .v-leave-from {
    opacity: 1;
    transform: translateY(0);
  }
  
  .v-enter-active,
  .v-leave-active {
    transition: opacity 1s ease;
  }
  </style>  

此时,列表添加、删除的元素是有动画的,但是由于添加或者删除导致的其他需要移动的元素是没有动画的。可以使用一个新增的 v-move 的 class 来完成动画,它会在元素改变位置的过程中应用。

<transition-group> 组件的属性:

  1. 除了 mode 过渡模式不可用外,其他 <transition> 组件的属性都可用。
  2. tag:默认情况下,<transition-group> 不会渲染成一个元素的包裹器,可以通过指定 tag 属性将其渲染为想要的元素。

动画的 class 类:

  1. <transition>中动画的 class 类都可用。
  2. v-move:会在元素改变位置的过程中应用。
      <template>
        <transition-group tag="div">
          <template v-for="item in nums" :key="item">
            <div>{{ item }}</div>
          </template>
        </transition-group>
        <button @click="handleAdd">插入</button>
        <button @click="handlDelete">删除</button>
      </template>
      
      <script setup>
      import {ref} from 'vue'
      const nums = ref([0, 1, 2, 3, 4, 5])
      const randomIndex = () => {
        return Math.floor(Math.random() * nums.value.length)
      }
      const handleAdd = () => {
        nums.value.splice(randomIndex(), 0, nums.value.length)
      }
      const handlDelete = () => {
        nums.value.splice(randomIndex(), 1)
      }
      </script>
      
      <style scoped>
      .v-enter-from, 
      .v-leave-to {
        opacity: 0;
        transform: translateY(30px);
      }
      
      .v-enter-to,
      .v-leave-from {
        opacity: 1;
        transform: translateY(0);
      }
      
      .v-enter-active,
      .v-leave-active,
      /* 为其他移动的元素添加动画 */
      .v-move {
        transition: all 3s ease;
      }
    
      /* 元素离开时设置绝对定位,否则的话,离开动画的过程中,被删除元素仍然占据位置,导致其他需要移动的元素无法运用动画 */
      .v-leave-active {
        position: absolute;
      }
      </style>
    
    上面的示例中,列表添加、删除的元素是有动画的,但是由于添加或者删除而导致的其他需要移动的元素是没有动画的。可以使用 新增的 v-move 的 class 来完成动画。

http://www.kler.cn/a/512557.html

相关文章:

  • kafka学习笔记7 性能测试 —— 筑梦之路
  • 《keras 3 内卷神经网络》
  • 【机器学习实战中阶】比特币价格预测
  • leetcode刷题记录(七十二)——146. LRU 缓存
  • 【2025】拥抱未来 砥砺前行
  • vue+高德API搭建前端Echarts图表页面
  • 【语言处理和机器学习】概述篇(基础小白入门篇)
  • 蒙操作系统(HarmonyOS)
  • 具身智能新突破!Physical Intelligence推出机器人动作tokenizer,训练提速5倍
  • 高级java每日一道面试题-2025年01月20日-数据库篇-并发事务带来哪些问题?
  • JeecgBoot 低代码 AI 大模型集成 DeepSeek
  • 【云岚到家】-day03-门户缓存实现实战
  • 服务器日志自动上传到阿里云OSS备份
  • 【网络协议】【http】【https】RSA+AES-TLS1.2
  • Unity3D学习笔记(一)
  • Python绘制数据地图-MovingPandas
  • 【Qt 常用控件】显示类控件——QLabel
  • 最长递增子序列问题(Longest Increasing Subsequence),动态规划法解决,贪心算法 + 二分查找优化
  • 鸿蒙子组件根据数据,刷新item Ui的规范
  • 重讲Diffusion Policy(从公式和代码角度): 个人最看好的机器人操控算法
  • 计算机网络常见协议
  • JS宏实例:隐藏窗口读取数据与简单的数据处理
  • debian中apt的配置与解析
  • 理解 package-lock.json 何时推送与忽略
  • 流行的开源高性能数据同步工具 - Apache SeaTunnel 整体架构运行原理
  • 【ARM】MDK-语言标准执行报错Error:268