# 1.transition 基本用法
- v-enter-from:定义进入过渡的开始状态。在原始被插入之前生效,在元素被插入之后的下一帧移除。
- v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡 / 动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
- v-enter-to:定义进入过渡的介绍状态。在元素被插入之后下一帧生效 (与此同时 v-enter-from 被移除),在过渡 / 动画完成之后移除
- v-leave-from:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
- v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡 / 动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
- v-leave-to:离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave-from 被删除),在过渡 / 动画完成之后移除。
- class 的 name 命名规则:
- 如果我们使用的是一个没有 name 的 transition,那么所有的 class 是以 v- 做为默认前缀;
- 如果我们添加了一个 name 属性,比如 <transitions name:"neko">, 那么所有的 class 会以 neko- 开头;
- 执行顺序:

- type:Vue 为了指定过渡的完成,内部是在监听 transitionend 或 animationend,到底使用哪一个取决于元素应用的 CSS 规则:
- 如果只使用了其中的一个,那么 Vue 能自动失败类型并设置监听;
- 但如果同时使用:可能某一个动画执行结束时,另外一个动画还没有结束,可以设置 type 属性为 animation 或者 transition 来明确告知 Vue 监听的类型
- duration:可以设置两种类型的值
- number 类型:同时设置进入和离开的过渡时间;
- object 类型:分别设置进入和离开的过渡时间;
- mode:
- in-out:上个要消失的元素或组件先消失,等到消失完之后,下一个组件或者元素再进入。
- out-in:下一个要出现的组件或者元素先进入,等到进入完之后,上一个组件或者元素再消失。
- appear:页面初始化时就默认执行一次动画。只写 appear 属性不赋值默认为 true
# 2.transition 基本使用
// App.vue | |
<template> | |
<div class="app"> | |
<div><button @click="isShow = !isShow">显示/隐藏</button></div> | |
<transition name="neko"> //定义 class name 名 | |
<h3 v-if="isShow">Hello World!</h3> | |
</transition> | |
</div> | |
</template> | |
<script> | |
export default { | |
data() { | |
return { | |
isShow: true, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
/* 进入过渡开始的状态 */ | |
.neko-enter-from { | |
opacity: 0; | |
} | |
/* 进入过渡生效的状态 */ | |
.neko-enter-active { | |
transition: opacity 1s ease; | |
} | |
/* 进入过渡结束的状态 */ | |
.neko-enter-to { | |
opacity: 1; /* 浏览器显示默认为 1,可省略不写 */ | |
} | |
/* 离开过渡开始的状态 */ | |
.neko-leave-from { | |
opacity: 1; /* 可不写 */ | |
} | |
/* 离地过渡生效的状态 */ | |
.neko-leave-active { | |
transition: opacity 1s ease; | |
} | |
/* 离过渡结束的状态 */ | |
.neko-leave-to { | |
opacity: 0; | |
} | |
</style> |
参考结果:

# 3.animation 定义动画
// App.vue | |
<template> | |
<div class="app"> | |
<div><button @click="isShow = !isShow">显示/隐藏</button></div> | |
<transition name="neko"> | |
<h3 class="title" v-if="isShow">你好呀,李银河!</h3> | |
</transition> | |
</div> | |
</template> | |
<script> | |
export default { | |
data() { | |
return { | |
isShow: true, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
.title { | |
display: inline-block; | |
background-color: pink; | |
} | |
.neko-enter-active { | |
animation: bounce 1s ease; | |
} | |
.neko-leave-active { | |
animation: bounce 1s ease reverse; | |
} | |
@keyframes bounce { | |
0% { | |
transform: scale(0); | |
} | |
50% { | |
transform: scale(1.2); | |
} | |
100% { | |
transform: scale(1); | |
} | |
} | |
</style> |
参考结果:

# 4. type & duration
// App | |
<template> | |
<div class="app"> | |
<div><button @click="isShow = !isShow">显示/隐藏</button></div> | |
<transition | |
name="neko" | |
type="transition" | |
:duration="{ enter: 4000, leave: 1000 }" | |
> | |
<h3 class="title" v-if="isShow">你好呀,李银河!</h3> | |
</transition> | |
</div> | |
</template> | |
<script> | |
export default { | |
data() { | |
return { | |
isShow: true, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
.title { | |
display: inline-block; | |
background-color: pink; | |
} | |
/* 因为设置了 type 和 duration 属性, 所以会以不超出动画设置的时间为前提,优先执行 type 和 duration 里面定义的方式与时间。比如 {enter: 1000, leave: 1000} 这种就不能达到满足的效果 ,会得到执行的效果是 animation 执行 1s 的结果。而如果自己定义的时间进入和离开 { enter: 5000, leave: 5000 } 都比 animation 定义的时间长,则会隐藏失效 */ | |
.neko-enter-active { | |
animation: bounce 3s ease; | |
} | |
.neko-leave-active { | |
animation: bounce 3s ease reverse; | |
} | |
@keyframes bounce { | |
0% { | |
transform: scale(0); | |
} | |
50% { | |
transform: scale(1.2); | |
} | |
100% { | |
transform: scale(1); | |
} | |
} | |
</style> |
参考结果:

# 5.mode 元素切换顺序
// App.vue | |
<template> | |
<div class="app"> | |
<div><button @click="isShow = !isShow">显示/隐藏</button></div> | |
<transition | |
name="neko" | |
type="transition" | |
:duration="{ enter: 1000, leave: 1000 }" | |
mode="out-in" | |
> | |
<h3 class="title" v-if="isShow">你好呀,李银河!</h3> | |
<h3 class="title" v-else>Hello World!</h3> | |
</transition> | |
</div> | |
</template> | |
<script> | |
export default { | |
data() { | |
return { | |
isShow: true, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
.title { | |
display: inline-block; | |
background-color: pink; | |
} | |
.neko-enter-active { | |
animation: bounce 1s ease; | |
} | |
.neko-leave-active { | |
animation: bounce 1s ease reverse; | |
} | |
@keyframes bounce { | |
0% { | |
transform: scale(0); | |
} | |
50% { | |
transform: scale(1.2); | |
} | |
100% { | |
transform: scale(1); | |
} | |
} | |
</style> |
参考结果:out-in 先等你好呀,李银河!消失,再让 Hello World!显示

# 6.component 切换
# Home
<template> | |
<div> | |
<span>我是Home组件</span> | |
</div> | |
</template> | |
<script> | |
export default {}; | |
</script> | |
<style scoped></style> |
# About
<template> | |
<div> | |
<span>我是About组件</span> | |
</div> | |
</template> | |
<script> | |
export default {}; | |
</script> | |
<style scoped></style> |
# App1
<template> | |
<div class="app"> | |
<div><button @click="isShow = !isShow">显示/隐藏</button></div> | |
<transition | |
name="neko" | |
type="transition" | |
:duration="{ enter: 1000, leave: 1000 }" | |
mode="out-in" | |
> | |
<component :is="isShow ? 'home' : 'about'"></component> | |
</transition> | |
</div> | |
</template> | |
<script> | |
import Home from "./Home"; | |
import About from "./About"; | |
export default { | |
components: { | |
Home, | |
About, | |
}, | |
data() { | |
return { | |
isShow: true, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
.title { | |
display: inline-block; | |
background-color: pink; | |
} | |
.neko-enter-active { | |
animation: bounce 1s ease; | |
} | |
.neko-leave-active { | |
animation: bounce 1s ease reverse; | |
} | |
@keyframes bounce { | |
0% { | |
transform: scale(0); | |
} | |
50% { | |
transform: scale(1.2); | |
} | |
100% { | |
transform: scale(1); | |
} | |
} | |
</style> |
参考结果:

# App2
<template> | |
<div class="app"> | |
<div><button @click="isShow = !isShow">显示/隐藏</button></div> | |
<transition | |
name="neko" | |
type="transition" | |
:duration="{ enter: 1000, leave: 1000 }" | |
mode="out-in" | |
appear | |
> | |
<component :is="isShow ? 'home' : 'about'"></component> | |
</transition> | |
</div> | |
</template> | |
<script> | |
import Home from "./Home"; | |
import About from "./About"; | |
export default { | |
components: { | |
Home, | |
About, | |
}, | |
data() { | |
return { | |
isShow: true, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
.title { | |
display: inline-block; | |
background-color: pink; | |
} | |
.neko-enter-active { | |
animation: bounce 1s ease; | |
} | |
.neko-leave-active { | |
animation: bounce 1s ease reverse; | |
} | |
@keyframes bounce { | |
0% { | |
transform: scale(0); | |
} | |
50% { | |
transform: scale(1.2); | |
} | |
100% { | |
transform: scale(1); | |
} | |
} | |
</style> |
参考结果:
