transition实现单元素/单组件的过渡和动画
Vue中使用css做动画和过渡
单元素/单组件的入场和出场过渡
什么是单元素/单组件
形如下面这样,模板中根div中只有一个div,叫单元素。同理,如果把这个div换成一个组件,那么就是一个单组件
template: `
<div>
// 单元素
<div class="transition" :style="styleObj">hello world</div>
<button @click="handleClick">切换</button>
</div>
`
什么是入场/出场
当页面中的DOM元素从显示状态到隐藏状态叫“入场”,当页面中的DOM元素从隐藏状态到显示状态叫“入场”
transition标签搭配固定的class,完成入场和出场过渡
【敲代码】
<style>
.v-enter-from{
opacity: 0;
}
.v-enter-active{
transition: opacity 2s ease-in-out;
}
.v-enter-to{
opacity: 1;
}
.v-leave-from{
opacity: 1;
}
.v-leave-active{
transition: opacity 2s ease-in-out;
}
.v-leave-to{
opacity: 0;
}
</style>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
备注
v-enter-from
: 入场动画的初始状态v-enter-active
: 设定整个入场动画的状态具体如何展示,如,动画持续的时间,过渡的动画类型c-enter-to
: 入场动画的结束状态v-leave-from
:出场动画的初始状态v-leave-active
:设定整个出场动画的状态具体如何展示,如,动画持续的时间,过渡的动画类型v-leave-to
:出场动画的结束状态
简写
不管是出场还是出场,由于默认opacity是1,可以省略不写,
因此下面的状态可以不写:
.v-enter-to{
opacity: 1;
}
.v-leave-from{
opacity: 1;
}
实现动画
【敲代码】
@keyframes shake{
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
.v-enter-active{
animation: shake 3s;
}
.v-leave-active{
animation: shake 3s;
}
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
备注
实现动画效果,相比过渡效果更简单一点,只依赖2个样式 v-leave-active
和v-enter-active
使用transition上的name属性自定义与之搭配的class名的前缀
前面同transtion
标签搭配的样式名都是固定的,如:v-enter-from
、v-enter-active
、c-enter-to
等都是叫v-xxx
其实我们也可以自定义命名这些样式名
我们只需要给transtion
标签,加上name属性,这样与之搭配的样式名就以这个name属性对应的值开头了
【敲代码】
@keyframes shake{
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
.hello-enter-active{
animation: shake 3s;
}
.hello-leave-active{
animation: shake 3s;
}
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition name="hello">
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
直接自定义与transition搭配的所有的class名
具体方法是:在transtion
标签上使用诸如:
enter-active-class="xxx"
、leave-active-class="yyy"
......
那么在定义class的时候就直接写.xxx{} .yyy{}
就可以定义动画的样式了
【敲代码】
@keyframes shake{
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
.hello{
animation: shake 3s;
}
.bye{
animation: shake 3s;
}
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition
enter-active-class="hello"
leave-active-class="bye"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
自定义class名的好处
使用自定义class的好处就是可以做些更复杂的css动画,而却可以使用第三方的css库
eg: 我们可以使用animate.css库实现有趣的动画效果
如何与动画库结合使用呢?
- 首先我们自己就不要再定义动画效果了,直接使用动画库中提供的动画
- 接着我们只需要在入场和出场动画执行过程中使用自定义样式指定animate为我们提供好的class即可:
enter-active-class='animate__animated animate__bounce'
、leave-active-class='animate__animated animate__bounce'
- 当然animate库中还有其他动画,不止
animate__bounce
这样的弹跳动画,当然不论添加什么动画class,animate__animated
class是不需要有的
【敲代码】
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition
enter-active-class="animate__animated animate__bounce"
leave-active-class="animate__animated animate__bounce"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
动画的同时有过渡
【敲代码】
@keyframes shake{
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
.v-enter-from{
color: red;
}
.v-enter-active{
animation: shake 3s;
transition: all 3s ease-in;
}
.v-enter-to{
color: green;
}
.v-leave-from{
color: green;
}
.v-leave-active{
animation: shake 3s;
transition: all 3s ease-out;
}
.v-leave-to{
color: red;
}
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
【运行结果】
动画和过渡时间不一致时,指定以某个的时间为主
比如:动画效果执行3s,过渡效果执行10秒,现在我们想以动画效果为主,3s动画效果结束后,过渡效果也跟着结束
在transition标签上使用type="animation"的方式,指定以动画时间为主
【敲代码】
@keyframes shake{
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
.v-enter-from{
color: red;
}
.v-enter-active{
animation: shake 3s;
transition: all 10s ease-in;
}
.v-enter-to{
color: green;
}
.v-leave-from{
color: green;
}
.v-leave-active{
animation: shake 3s;
transition: all 10s ease-out;
}
.v-leave-to{
color: red;
}
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition type="animation">
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
不加type="animation"
时的效果:颜色过渡10s
加type="animation"
时的效果:颜色过渡3秒完成
使用:duration强制指定动画和过渡持续时间
1. :duration为数字,:duration="1000"指定动画和过渡持续时间
【敲代码】
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition :duration="1000">
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
2. duration为对象,:duration="{}"指定动画和过渡的入场时间和出场时间
【敲代码】
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
}
},
template: `
<div>
<transition :duration="{enter: 1000,leave: 3000}">
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
Vue中使用JS做动画和过渡
具体方法是:
- 使用
:css="false"
表示不使用css做动画 - Vue中提供了一些钩子(类似生命周期函数,某一时刻自动执行的函数)供我们使用
【敲代码】
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show
},
handleBeforeEnter(el){
el.style.color = 'red'
},
handleEnterActive(el,done){
const animation = setInterval(() => {
const color = el.style.color
if(color === 'red'){
el.style.color = 'green'
}else{
el.style.color = 'red'
}
}, 1000);
setTimeout(() => {
clearInterval(animation)
done()
}, 3000);
}
},
template: `
<div>
<transition
:css = "false"
@before-enter = "handleBeforeEnter"
@enter = "handleEnterActive"
@after-enter = "handleEnterEnd"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
备注
@before-enter="xxx"
,在入场开始之前自动执行的函数,函数xxx中可以使用参数el接收vue帮我们传递过来的DOM元素@enter="xxx"
,动画开始时自动执行的函数,函数xxx,接收2个参数,一个是DOM元素el,另外一个是done,它的作用是告诉@after-enter
中的函数,当前动画已结束,当执行done()后@after-enter
才能感知到动画结束了,才能执行动画结束后的逻辑@after-enter="xxx"
,动画结束时自动执行的函数,函数xxx中接收1个参数el- 同理出场动画的钩子:
@before-leave="xxx"
、@leave="xxx"
、@after-leave="xxx"
转载自:https://juejin.cn/post/7241749527987650620