1 认识Vue的动画原理
2 动画中常见类的作用
3 animation动画实现
4 动画的常见属性设置
5 列表元素动画组实现
6 列表元素的移动动画
认识Vue的动画原理
利用transition标签和一系列的动画类来控制标签的动画效果。
transition标签的本质是帮你添加和删除动画类的。
transition标签的name属性用来区别动画类的。(如果不添加name属性,那么transition标签会默认找v-enter-from等等的v开头的动画类属性)
<template> <div class="app"> <div> <button @click="isShow = !isShow">切换</button> </div> <transition name="why"> <h2 v-if="isShow">哈哈哈哈</h2> </transition> </div> </template> <script setup> import { ref } from 'vue'; const isShow = ref(false) </script> <style scoped> h2 { display: inline-block; } .why-enter-from, .why-leave-to { opacity: 0; transform: scale(0.6); } .why-enter-to, .why-leave-from { opacity: 1; transform: scale(1); } .why-enter-active, .why-leave-active { transition: all 2s ease; } </style>
animation动画实现
和普通的使用帧动画差不多。利用@keyframe和animation来实现
<template> <div class="app"> <div> <button @click="isShow = !isShow">切换</button> </div> <transition name="why"> <h2 v-if="isShow"> 要是有些事我没说,地坛,你别以为是我忘了,我什么也没忘,但是有些事只适合收藏。不能说,也不能想,却又不能忘。它们不能变成语言,它们无法变成语言,一旦变成语言就不再是它们了。它们是一片朦胧的温馨与寂寥,是一片成熟的希望与绝望,它们的领地只有两处:心与坟墓。比如说邮票,有些是用于寄信的,有些仅仅是为了收藏。 </h2> </transition> </div> </template> <script setup> import { ref } from 'vue'; const isShow = ref(false) </script> <style scoped> h2 { display: inline-block; } .why-enter-active { animation: whyAnim 2s ease; } .why-leave-active { /* animation: whyLeaveAnim 2s ease; */ animation: whyAnim 2s ease reverse; } @keyframes whyAnim { 0% { transform: scale(0); opacity: 0; } 50% { transform: scale(1.2); opacity: 0.5; } 100% { transform: scale(1); opacity: 1; } } @keyframes whyLeaveAnim { 0% { transform: translateX(0); opacity: 1; } 100% { transform: translateX(-500px); opacity: 0; } } </style>
动画属性设置(一)
type属性不要乱用,少用甚至不用。
<template> <div class="app"> <div> <button @click="isShow = !isShow">切换</button> </div> <transition name="why"> <h2 v-if="isShow"> 要是有些事我没说,地坛,你别以为是我忘了,我什么也没忘,但是有些事只适合收藏。不能说,也不能想,却又不能忘。它们不能变成语言,它们无法变成语言,一旦变成语言就不再是它们了。它们是一片朦胧的温馨与寂寥,是一片成熟的希望与绝望,它们的领地只有两处:心与坟墓。比如说邮票,有些是用于寄信的,有些仅仅是为了收藏。 </h2> </transition> </div> </template> <script setup> import { ref } from 'vue'; const isShow = ref(false) </script> <style scoped> h2 { display: inline-block; } /* transition */ .why-enter-from, .why-leave-to { opacity: 0; } .why-enter-to, .why-leave-from { opacity: 1; } .why-enter-active { animation: whyAnim 2s ease; transition: opacity 2s ease; } .why-leave-active { animation: whyAnim 2s ease reverse; transition: opacity 2s ease; } @keyframes whyAnim { 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } </style>
动画属性设置(二)
mode属性可以设置动画组件的播放顺序,一个动画结束了才会执行另外一个动画。
<template> <div class="app"> <div> <button @click="isShow = !isShow">切换</button> </div> <!-- mode属性掌握 --> <transition name="why" mode="out-in"> <h2 v-if="isShow">哈哈哈</h2> <h2 v-else>呵呵呵</h2> </transition> </div> </template> <script setup> import { ref } from 'vue'; const isShow = ref(true) </script> <style scoped> h2 { display: inline-block; } /* transition */ .why-enter-from, .why-leave-to { opacity: 0; } .why-enter-to, .why-leave-from { opacity: 1; } .why-enter-active { animation: whyAnim 2s ease; transition: opacity 2s ease; } .why-leave-active { animation: whyAnim 2s ease reverse; transition: opacity 2s ease; } @keyframes whyAnim { 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } </style>
动画组件动画
为两个组件的进入和退出制作动画
<template> <div class="app"> <div> <button @click="isShow = !isShow">切换</button> </div> <!-- mode属性掌握 --> <transition name="why" mode="out-in" appear=""> <component :is=" isShow ? 'home': 'about'"></component> </transition> </div> </template> <script> import Home from './pages/Home.vue' import About from './pages/About.vue' export default { components: { Home, About } } </script> <script setup> import { ref } from 'vue'; const isShow = ref(true) </script> <style scoped> h2 { display: inline-block; } /* transition */ .why-enter-from, .why-leave-to { opacity: 0; } .why-enter-to, .why-leave-from { opacity: 1; } .why-enter-active { animation: whyAnim 2s ease; transition: opacity 2s ease; } .why-leave-active { animation: whyAnim 2s ease reverse; transition: opacity 2s ease; } @keyframes whyAnim { 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } </style>
打乱序列的数组动画:
乱用underscore动画库来为数组的乱序制作动画,并且使用transition-group来包裹数组
<template> <div class="app"> <button @click="addNumber">添加数字</button> <button @click="removeNumber">删除数字</button> <button @click="shuffleNumber">打乱数字</button> <transition-group tag="div" name="why"> <template v-for="item in nums" :key="item"> <span>{{ item }}</span> </template> </transition-group> </div> </template> <script setup> import { reactive, ref } from 'vue'; import { shuffle } from "underscore"; const nums = ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) const addNumber = () => { nums.value.splice(randomIndex(), 0, nums.value.length) } const removeNumber = () => { nums.value.splice(randomIndex(), 1) } const shuffleNumber = () => { nums.value = shuffle(nums.value) } const randomIndex = () => { return Math.floor(Math.random() * nums.value.length) } </script> <style scoped> span { margin-right: 10px; display: inline-block; } .why-enter-from, .why-leave-to { opacity: 0; transform: translateY(30px); } .why-enter-to, .why-leave-from { opacity: 1; transform: translateY(0); } .why-enter-active, .why-leave-active { transition: all 2s ease; } .why-leave-active { position: absolute; } /* 针对其他移动的阶段需要的动画 */ .why-move { transition: all 2s ease; } </style>