Vue 提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画:
Transition会在一个元素或组件进入和离开 DOM 时应用动画。
TransitionGroup会在一个v-for列表中的元素或组件被插入,移动,或移除时应用动画。
Transition
1. Transition 组件不带 name 属性,默认使用 v- 开头
<button @click="isShow1 = !isShow1">动画1</button>
<!-- 没有设置name属性,样式中使用默认的 v 开头 -->
<Transition>
<h2 v-if="isShow1">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈11111</h2>
</Transition>
// 在css中定义动画样式
.v-enter-active,
.v-leave-active {
transition: opacity 1s ease;
}
2. Transition 组件中设置了 name 属性,样式以 name值- 开头
<button @click="isShow2 = !isShow2">动画2</button>
<!-- 设置name属性,样式中使用设置的 name值 开头 -->
<Transition name="cxm">
<h2 v-if="isShow2">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈22222</h2>
</Transition>
/* 动画2样式 */
.cxm-enter-active,
.cxm-leave-active {
transition: opacity 1s ease;
}
3. 使用@keykeyframes 动画
<!-- 使用@keykeyframes 动画 -->
<button @click="isShow3 = !isShow3">动画3</button>
<Transition name="cxm3">
<h2 v-if="isShow3">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈33333</h2>
</Transition>
/* 动画3样式 */
.cxm3-enter-active {
animation: dh 1s ease;
}
.cxm3-leave-active {
animation: dh 1s ease reverse;
}
@keyframes dh {
0% {
opacity: 0;
transform: translateX(100px);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
4. 使用第三方动画库animate.css
<!-- 使用第三方库 animate.css动画库 -->
<button @click="isShow4 = !isShow4">动画4</button>
<Transition
enter-active-class="animate__animated animate__backInLeft"
leave-active-class="animate__animated animate__backOutLeft"
>
<h2 v-if="isShow4">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈44444</h2>
</Transition>
// 在script中引入第三方库
import "animate.css";
5. 过渡模式 mode
- 【注】过渡模式中:“多个组件或者元素” 同一时间只能有一个显示/创建
<template>
<!-- 过渡模式 mode -->
<button @click="isShow5 = !isShow5">过渡模式</button>
<Transition name="cxm3" mode="out-in">
<!--
“多个组件或者元素” 同一时间只能有一个显示/创建
out-in : 先显示/创建 离开的元素,再显示/创建 进入的元素(先出后进)
in-out : 先显示/创建 进入的元素,再显示/创建 离开的元素(先进后出)
-->
<h2 v-if="isShow5">111111111111111111111111</h2>
<p v-else>22222222222222222222222222222</p>
</Transition>
</template>
<script>
import "animate.css";
export default {
data() {
return {
isShow5: true,
};
},
};
</script>
<style>
/* 动画3样式 */
.cxm3-enter-active {
animation: dh 1s ease;
}
.cxm3-leave-active {
animation: dh 1s ease reverse;
}
@keyframes dh {
0% {
opacity: 0;
transform: translateX(100px);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
</style>
TransitionGroup 列表过渡
- v-enter-active:进入过渡生效时的状态
- v-leave-active:离开过渡生效时的状态
- tag:转变为对应的标签
- name:过渡的名字
<template>
<input type="text" v-model="mytext" />
<button @click="handleClick()">add</button>
<!-- <ul> -->
<TransitionGroup name="cxm" tag="ul">
<li v-for="(item, index) in list" :key="item">
{{ item }}--{{ index }}
<button @click="handleDel(index)">del</button>
</li>
</TransitionGroup>
<!-- </ul> -->
</template>
<script>
export default {
data() {
return {
mytext: "",
list: ["111", "222", "333"],
};
},
methods: {
handleClick() {
this.list.push(this.mytext);
//清空输入框,value绑定mytext
this.mytext = "";
},
//删除
handleDel(index) {
console.log("del", index);
//删除第几个???
this.list.splice(index, 1);
},
},
};
</script>
<style>
.cxm-enter-active {
animation: dh 1s ease;
}
.cxm-leave-active {
animation: dh 1s ease reverse;
}
@keyframes dh {
0% {
opacity: 0;
transform: translateX(100px);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
.cxm-move /* 对移动中的元素应用的过渡 */ {
transition: all 1s ease;
}
/* 确保将离开的元素从布局流中删除
以便能够正确地计算移动的动画。 */
.cxm-leave-active {
position: absolute;
}
</style>
封装组件 - 可复用动画
App.vue
<template>
<button @click="isShow = !isShow">切换</button>
<MyTransition>
<h2 v-if="isShow">红红火火恍恍惚惚哈哈哈哈哈哈哈哈</h2>
</MyTransition>
</template>
<script>
import MyTransition from "./MyTransition.vue";
export default {
components: {
MyTransition,
},
data() {
return {
isShow: true,
};
},
};
</script>
动画组件
<template>
<Transition name="cxm">
<slot></slot>
</Transition>
</template>
<script>
export default {};
</script>
<style>
.cxm-enter-active {
animation: dh 1s ease;
}
.cxm-leave-active {
animation: dh 1s ease reverse;
}
@keyframes dh {
0% {
opacity: 0;
transform: translateX(100px);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
</style>