1. 介绍
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
- 条件渲染 (使用 v-if)
- 条件展示 (使用 v-show)
- 动态组件
- 组件根节点
2、单元素,单组件的入场出场
2.1 基础写法
如果对 transition 重命名(使用 name 属性),则 v-enter-from 要使用 name-enter-from
效果展示
<template>
<div>
<transition>
<div v-show="show">transition</div>
</transition>
<button @click="handleChange">切换</button>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
},
methods: {
handleChange() {
this.show = !this.show
}
}
}
</script>
<style lang="less" scoped>
.v-enter {
opacity: 0;
}
.v-enter-active {
transition: opacity 3s ease-out;
}
.v-enter-to {
opacity: 1;
}
.v-leave {
opacity: 1;
}
.v-leave-active {
transition: opacity 1s ease-out;
}
.v-leave-to {
opacity: 0;
}
</style>
2.2 结合 keyframes 使用
效果展示
<template>
<div>
<transition>
<div v-show="show">transition</div>
</transition>
<button @click="handleChange">切换</button>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
},
methods: {
handleChange() {
this.show = !this.show
}
}
}
</script>
<style lang="less" scoped>
@keyframes shake {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100% {
transform: translateX(50px);
}
}
.v-enter-active,
.v-leave-active {
animation: shake 3s;
}
</style>
2.3 结合 animate 动画库使用
通过 npm 下载,或者 CDN 引入
自定义动画名称,使用 animate 库的动画名称
效果展示
<template>
<div>
<transition
enter-active-class="animate__animated animate__bounce"
leave-active-class="animate__animated animate__flash"
>
<div v-show="show">
transition
</div>
</transition>
<button @click="handleChange">切换</button>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
},
methods: {
handleChange() {
this.show = !this.show
}
}
}
</script>
2.4 其他语法
- 如果同时有 transition 和 animation ,通过 type 控制优先级
- 通过 duration 控制时长,以毫秒计
- 通过 mode 控制动画执行顺序,appear 控制第一次是否有动画,也可以通过 component 的 is 属性控制
3. 列表动画
使用 transition-group 做列表动画,v-move 控制其他元素的动画效果,可能需要使用行内块元素
<template>
<div>
<button @click="add">Add</button>
<transition-group name="list">
<span v-for="item in items" :key="item" class="list-item">
{{ item }}
</span>
</transition-group>
</div>
</template>
<script>
export default {
data() {
return {
items: [1, 2, 3, 4, 5, 6, 7, 8, 9]
}
},
methods: {
add() {
this.items.splice(2, 0, this.items.length + 1)
}
}
}
</script>
<style lang="less" scoped>
.list-enter {
opacity: 0;
transform: translateY(30px);
}
.list-enter-active {
transition: all 1s ease-in;
}
.list-enter-to {
opacity: 1;
transform: translateY(0px);
}
.v-move {
transition: all 1s ease-in;
}
.list-item {
display: inline-block;
margin-right: 10px;
}
</style>
不忘初心