animate.css
安装:
npm install animate.css -save在文件中添加引用:
import "animate.css";第一种使用方法和普通的animation用法差不多,需要使用动画的元素要被<transition>包裹,并在style中通过动画的名字使用animate.css的样式:
<template>
<div class="app">
<div>
<button @click="isShow=!isShow">显示/隐藏</button>
</div>
<transition name="sk" mode="out-in" :appear="true">
<h2 class="title" v-if="isShow">hello world</h2>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
isShow: true
}
},
}
</script>
<style scoped>
.title{
display: inline-block;
}
.sk-enter-active{
animation: rollIn 1s ease-in
}
.sk-leave-active{
animation: rollOut 1s ease-in
}
</style>第二种用法是直接在transition标签中加入enter-active-class和leave-active-class属性,属性值为”animate__animated “+动画名称:
<transition enter-active-class="animate__animated animate__rotateIn"
leave-active-class="animate__animated animate__rotateOutDownLeft">
<h2 class="title" v-if="isShow">hello world</h2>
</transition>此外还有一些属性例如enter-to-class、enter-from-class、leave-to-class、leave-from-class
gsap库
安装:
npm install gsap -save导入:
import gsap from "gsap";transition的生命周期回调:
<template>
<div class="app">
<div>
<button @click="isShow=!isShow">显示/隐藏</button>
</div>
<transition @before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave">
<h2 class="title" v-if="isShow">hello world</h2>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
isShow: true
}
},
methods: {
beforeEnter() {
console.log("beforeEnter");
},
enter() {
console.log("enter");
},
afterEnter() {
console.log("afterEnter");
},
beforeLeave() {
console.log("beforeLeave");
},
leave() {
console.log("leave");
},
afterLeave() {
console.log("afterLeave");
},
},
}
</script>这些生命周期钩子对应了css中的enter-to-class等类。
使用gsap,就是在这些回调的方法中使用gsap的方法。其中from是从一个自定义的状态到结束状态,to方法是从初始状态到一个自定义的状态:
<template>
<div class="app">
<div>
<button @click="isShow=!isShow">显示/隐藏</button>
</div>
<transition @enter="enter"
@leave="leave"
:css="false">
<h2 class="title" v-if="isShow">hello world</h2>
</transition>
</div>
</template>
<script>
import gsap from "gsap";
export default {
data() {
return {
isShow: true,
distance: 200
}
},
methods: {
enter(el, done) {
console.log("enter");
gsap.from(el,{
scale:0,
x:this.distance,
// 默认是0.5s
duration:1,
// 如果不写时,默认在动画开始时同步回调done
onComplete: done
})
},
leave(el,done) {
console.log("leave");
gsap.to(el,{
scale:0,
x:200,
duration:1,
onComplete:done
})
},
},
}
</script>其中回调方法中第一个参数el是指回调产生的元素,同时也需要传入给gsap,第二个参数是动画完成时的回调,一般需要在gasp的onComplete属性中写出。
transition的:css属性设置为false,可以跳过css检测,提高性能。
使用gsap的一个特点是通过JavaScript实现的,比较灵活。
利用gsap实现数字渐变效果
<template>
<div class="app">
<input type="number" step="100" v-model="counter">
<h2>当前计数:{{showNumber.toFixed(0)}}</h2>
</div>
</template>
<script>
import gsap from 'gsap';
export default {
data() {
return {
counter:0,
showNumber:0
}
},
watch:{
counter(newValue){
gsap.to(this,{
duration:1,
showNumber:newValue
})
}
}
}
</script>对数字进行观察,当数字发生变化时使用gsap的to方法,将要显示的数字变化在一个时期内变化到目标数字。
transition-group
transition-group有以下特点:
默认情况下,它不会渲染一个元素的包裹器,但是你可以指定一个元素并以tag attribute进行渲染;
过渡模式不可用,因为我们不再相互切换特有的元素;
内部元素总是需要提供唯一的key attribute值;
CSS过渡的类将会应用在内部的元素中,而不是这个组/容器本身;
基本使用:对一个列表中删除或增加的数字增加动画
在transition-group标签中增加一个tag属性,那么其中的元素都会被包裹在这个tag指定的容器里面:
<template>
<div>
<button @click="addNum">添加数字</button>
<button @click="removeNum">删除数字</button>
<transition-group tag="p" name="sk">
<span v-for="item in numbers" :key="item" class="item">
{{item}}
</span>
</transition-group>
</div>
</template>增加、删除数字的逻辑:
<script>
export default {
data() {
return {
numbers:[1,2,3,4,5,6,7,8,9],
numberCounter:10
}
},
methods: {
addNum(){
this.numbers.splice(this.randomIndex(),0,this.numberCounter++);
},
removeNum(){
this.numbers.splice(this.randomIndex(),1);
},
randomIndex(){
return Math.floor(Math.random()*this.numbers.length);
}
},
}
</script>动画的实现还是使用的transition的类:
<style scoped>
.item{
margin-right: 10px;
display: inline-block;
}
.sk-enter-from,
.sk-leave-to{
opacity: 0;
transform: translateY(30px);
}
.sk-enter-active,
.sk-leave-active{
transition: all 1s ease;
}
</style>为队列中的其它数字增加动画效果:vue中已经帮助我们考虑到了这种情况,因此只需要使用transition的-move类就可以实现了:
<style scoped>
.item{
margin-right: 10px;
display: inline-block;
}
.sk-enter-from,
.sk-leave-to{
opacity: 0;
transform: translateY(30px);
}
.sk-enter-active,
.sk-leave-active{
transition: all 1s ease;
}
// 防止在删除过程中其它元素动画因为被占位了而不生效的问题
.sk-leave-active{
position: absolute;
}
.sk-move{
transition: transform 1s ease;
}
</style>列表的交替动画
<template>
<div>
<input v-model="keyword">
<transition-group tag="ul" name="sk" :css="false"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave">
<li v-for="(item,index) in showNames" :key="item" :data-index="index">
{{item}}
</li>
</transition-group>
</div>
</template>
<script>
import gsap from 'gsap';
export default {
data() {
return {
names:["abc","cba","nba","sk","lilei","hmm","kobe"],
keyword: ""
}
},
computed:{
showNames(){
return this.names.filter(item=>item.indexOf(this.keyword)!==-1)
}
},
methods: {
beforeEnter(el){
el.style.opacity=0;
el.style.height=0;
},
enter(el,done){
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
})
}
},
}
</script>通过gsap的delay属性,实现根据下标完成延时显示的效果。