CSS 过渡
- 文档中的例子
<template>
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show:true
}
}
}
</script>
<style scope>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
</style>
- Vue 封装了用于 transition 动画的 标签:
<transition></transition>
- transition 标签用有个 name 属性,这个属性传入了什么字符串,那么控制动画的类的开头就是什么。
- 比如:
<transition name="x"></transition>
- 控制动画的类名就是: .x-enter、.x-leave
- 控制动画的类
- .fade-enter
- 淡入动画开始的瞬间,可以理解为动画的第一帧。.fade-enter 类在第一帧结束后,就会消失,替换为 .fade-enter-to
- .fade-enter-to
- 淡入的过程中,.fade-enter-to 会一直持续到淡入结束
- .fade-enter-active
- 淡入过渡生效的状态。
- 同理,.fade-leave, .fade-leave-to, .fade-leave-active 为淡出瞬间、淡出过程中、淡出过渡生效状态 所以,文档中淡入淡出例子相当于以下写法:
- .fade-enter
<style scope>
.fade-enter-active,
.fade-leave-active {
transition: all .5s;
}
.fade-enter {
opacity: 0;
}
.fade-enter-to {
opacity: 1;
}
.fade-leave {
opacity: 1;
}
.fade-leave-to {
opacity: 0;
}
</style>
- 文档中的另一个例子:淡出时做一个侧移
<style scope>
.fade-enter-active{
transition: all .3s ease;
}
.fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.fade-enter {
opacity: 0;
transform: translateX(20px);
}
.fade-leave-to {
opacity: 0;
transform: translateX(20px);
}
</style>
animation 动画
- 文档中的例子
<template>
<div id="example-2">
<button @click="show = !show">Toggle show</button>
<transition name="bounce">
<p v-if="show">
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Mauris facilisis enim libero,
at lacinia diam fermentum id.
Pellentesque habitant morbi tristique senectus et netus.
</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show:true
}
}
}
</script>
<style scope>
/* 只定义动画过程中的过渡状态 */
.bounce-enter-active {
animation: bounce-in .5s;
}
/* 淡出动画反向执行 */
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
</style>
- 不使用 style 类来控制动画,而是使用 @keyframes 来自定义动画过程
- 使用 animation 来定义动画更为简洁,只需要定义好淡入和淡出过程中的状态
- animation 动画的最终状态一定要是正常状态
使用第三方库来制作动画
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<template>
<div id="example-3">
<button @click="show = !show">
Toggle render
</button>
<transition
enter-active-class="animated rollIn"
leave-active-class="animated rollOut"
>
<p v-if="show">
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Mauris facilisis enim libero,
at lacinia diam fermentum id.
Pellentesque habitant morbi tristique senectus et netus.
</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show:true
}
}
}
</script>
- 示例中使用了 animate.css 定义好的 rollIn 和 rollOut 类。
- 我们可以方便的通过
enter-active-class
和leave-active-class
更换类名来实现不同的 animate 提供的动画效果
多元素动画
- 按钮切换
<template>
<div id="example-4">
<transition name="fade">
<button key="on" v-if="status === 'off'"
@click="status = 'on'"
>on</button>
<button key="off" v-else
@click="status = 'off'"
>off</button>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
status: 'on'
}
}
}
</script>
<style scope>
.fade-enter-active,
.fade-leave-active {
transition: all 1s;
}
.fade-enter {
opacity: 0;
}
.fade-leave-to {
opacity: 0;
}
</style>
- 在一个按钮消失的同时,另一个按钮紧接着出现
-
Vue 提供了 mode 属性来控制这个过程
- mode="in-out" 新元素先完成过渡,旧元素再消失
- mode="out-in" 旧元素先完成过渡,新元素再出现
-
mode 属性作用于 transition 标签上
-
- 模拟轮播效果
<template>
<div id="example-4">
<transition name="fade">
<button key="on" v-if="status === 'off'"
@click="status = 'on'"
>on</button>
<button key="off" v-else
@click="status = 'off'"
>off</button>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
status: 'on'
}
}
}
</script>
<style scope>
.fade-enter-active,
.fade-leave-active {
transition: all 1s;
}
.fade-enter {
opacity: 0;
transform: translateX(100px);
}
.fade-leave-to {
opacity: 0;
transform: translateX(-100px);
}
button {
position: absolute;
}
</style>
- 模拟 tab切换
<template>
<div>
<button @click="view = 'A'">A</button>
<button @click="view = 'B'">B</button>
<transition name="component-fade" mode="out-in">
<component :is="view"></component>
</transition>
</div>
</template>
<script>
import A from "@/components/A.vue";
import B from "@/components/B.vue";
export default {
data() {
return {
view: "A",
};
},
components: { A, B },
};
</script>
<style scope>
.component-fade-enter-active,
.component-fade-leave-active {
transition: opacity 0.3s ease;
}
.component-fade-enter,
.component-fade-leave-to {
opacity: 0;
}
</style>
列表过渡
<template>
<div id="list-demo" class="demo">
<button v-on:click="add">Add</button>
<button v-on:click="remove">Remove</button>
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind: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],
nextNum: 10,
};
},
methods: {
randomIndex: function () {
return Math.floor(Math.random() * this.items.length);
},
add: function () {
this.items.splice(this.randomIndex(), 0, this.nextNum++);
},
remove: function () {
this.items.splice(this.randomIndex(), 1);
},
},
};
</script>
<style scope>
.list-item {
display: inline-block;
margin-right: 10px;
}
.list-enter-active,
.list-leave-active {
transition: all 1s;
}
.list-enter,
.list-leave-to {
opacity: 0;
transform: translateY(30px);
}
</style>
<transition-group>
组件- 不同于
<transition>
,它会以一个真实的元素呈现,默认为一个<span>
。我们可以通过tag
属性将其更换为其他元素。 mode
特性不能应用于<transition-group>
- 必须绑定不重复的
key
- 不同于