Vue.js 内置了一套过渡系统,该系统是 Vue.js 为 DOM 动画效果提供的一个特性。在插入、更新或者移除 DOM 时可以触发 CSS 过渡和动画,从而产生过渡效果。
Vue.js 提供了内置的过渡封装组件 transition,该组件用于包含要实现过渡效果的 DOM 元素。transition 组件只会把过渡效果应用到其包含的内容上,而不会额外渲染 DOM 元素。过渡封装组件的语法格式如下:
<transition name="nameoftransition">
<div>div>
transition>
语法中的 nameoftransition 参数用于自动生成 CSS 过渡类名。为元素和组件添加过渡效果主要应用在下列情形。
CSS 过渡的基础用法如下代码所示:
<div id="box">
<button v-on:click="show=!show">切换显示button>
<transition name="fade">
<p v-if="show">为了梦想,扬帆起航p>
transition>
div>
<script type="text/javascript">
//创建根实例
var vm =new Vue({
el :'#box',
data:{
show:true
}
});
script>
<style type="text/css">
/*设置CSS属性名和持续时间 */
.fade-enter-active,.fade-leave-active{
transition: opacity 2s
}
.fade-enter,.fade-leave-to{
opacity: 0
}
style>
通过单击“切换显示”按钮将变量 show 的值在 true 和 false 之间进行切换。如果为 true,则淡入显示 p 元素的内容,如果为 false,则淡出隐藏 p 元素的内容。运行结果如下图所示。
CSS 过渡其实就是一个淡入淡出的效果。当插入或删除包含在 transition 组件中的元素时,Vue.js 将执行如下操作:
Vue.js 在元素显示与隐藏的过渡中,提供了如下几个 class 来切换,class 类名及其说明如下表所示:
注意:对于这些在过渡中切换的类名来说,如果使用一个没有名字的 transition,则 v-是这些类名的默认前缀。
CSS 动画的用法和 CSS 过渡类似,但是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。示例代码如下所示:
<div id="box" align="center">
<button v-on:click="show=!show">切换显示button>
<transition name="scaling">
<p v-if="show">为了梦想,扬帆起航p>
transition>
div>
<script type="text/javascript">
//创建根实例
var vm =new Vue({
el :'#box',
data:{
show:true
}
});
script>
<style type="text/css">
p{
font: 30px "微软雅黑";/*设置字体和字体大小 */
margin: 30px auto;/*设置元素外边距*/
font-weight: 500;/*设置字体粗细*/
color: #35626;/*设置文字颜色*/
}
/* 设置 animation 属性的参数*/
.scaling-enter-active{
animation: scaling 1s
}
.scaling-leave-active{
animation: scaling 1s reverse
}
/* 设置元素的缩放转换*/
@keyframes scaling{
0%{
transform: scale(0);
}
50%{
transform: scale(1.2);
}
100%{
transform: scale(1);
}
}
style>
当单击“切换显示”按钮时,文本会以缩放的动画形式进行隐藏,再次单击该按钮,文本会以缩放的动画形式进行显示。运行结果如下图所示:
除了使用普通的类名(如 *-enter、 *-leave 等)之外,Vue.js 也允许自定义过渡类名。自定义的过渡类名的优先级高于普通的类名。通过自定义过渡类名可以使用过渡系统和其他第三方 CSS 动画库(如 animate.css)相结合,实现更丰富的动画效果。自定义过渡类名可以通过一下 6 个属性来实现:
在应用第三方 CSS 动画库文件 animate.css 的前提下,通过一个实例来了解自定义过渡类名的使用。代码如下:
<style type="text/css">
p{
font: 30px "微软雅黑";/*设置字体和字体大小 */
margin: 40px auto;/*设置元素外边距*/
font-weight: 500;/*设置字体粗细*/
color: #35626;/*设置文字颜色*/
}
style>
<div id="box" align="center">
<button v-on:click="show=!show">切换显示button>
<transition name="rotate" enter-active-class="animated rotateIn" leave-active-class="animated rotateOut">
<p v-if="show">为了梦想,扬帆起航p>
transition>
div>
<script type="text/javascript">
//创建根实例
var vm =new Vue({
el :'#box',
data:{
show:true
}
});
script>
最常见的多元素过渡是一个列表和描述这个列表为空消息的元素之间的过渡。在处理多元素过渡时可以使用 v-if 和 v-else。示例代码如下所示:
<style type="text/css">
/*设置过渡属性*/
.fade-enter,.fade-leave-to{
opacity: 0;
}
.fade-enter-active,.fade-leave-active{
transition: opacity .5s;
}
style>
<div id="box">
<button @click="clear">清空button>
<transition name="fade">
<ol v-if="items.length > 0">
<li v-for="item in items">{
{item}}li>
ol>
<p v-else>列表为空p>
transition>
div>
<script type="text/javascript">
//创建根实例
var vm =new Vue({
el :'#box',
data:{
items:['演员','歌手','导演']
},
methods:{
clear:function(){
this.items.splice(0);//清空数组
}
}
});
script>
当点击“清空”按钮时,页面内容变化会有一个过渡的效果,结果如下图所示:
当有相同标签名的多个元素进行切换时,需要通过 key 属性设置唯一的值来标记以让 Vue 区分它们。代码如下:
<style type="text/css">
/*设置过渡属性*/
.fade-enter,.fade-leave-to{
opacity: 0;
}
.fade-enter-active,.fade-leave-active{
transition: opacity .5s;
}
style>
<div id="box">
<button @click="show = !show">切换button>
<transition name="fade">
<p v-if="show" key="m">你曾经说过这样一句话:p>
<p v-else key="w">脚踏实地,保持初心,去做自己想做的事p>
transition>
div>
<script type="text/javascript">
//创建根实例
var vm =new Vue({
el :'#box',
data:{
show:true
}
});
script>
当点击“清空”按钮时,页面内容变化会有一个过渡的效果,结果如下图所示:
在 transition 的默认行为中,元素的进入和离开是同时发生的。由于同时生效的进入和离开的过渡不能满足所有要求。因此,Vue.js 提供了两种过渡模式:
应用 out-in 模式实现过渡的示例代码如下所示:
<style type="text/css">
/*设置过渡属性*/
.fade-enter,.fade-leave-to{
opacity: 0;
}
.fade-enter-active,.fade-leave-active{
transition: opacity .5s;
}
style>
<div id="box">
<transition name="fade" mode="out-in">
当每次单击按钮时,按钮中的文字都会在“显示”和“隐藏”之间进行过渡切换,运行结果如下图所示:
多个组件的过渡不需要使用 key 属性,只需要使用动态组件。示例代码如下所示:
<style type="text/css">
/*设置过渡属性*/
.fade-enter,.fade-leave-to{
opacity: 0;
}
.fade-enter-active,.fade-leave-active{
transition: opacity .5s;
}
style>
<div id="box">
<button @click="toggle">切换组件button>
<transition name="fade" mode="out-in">
<component :is="cName">component>
transition>
div>
<script type="text/javascript">
//创建根实例
var vm =new Vue({
el :'#box',
data:{
cName:'componentA'
},
components:{
componentA:{
//定义组件componentA
template:'组件A:你好
'
},
componentB:{
//定义组件componentB
template:'组件B:晓茗
'
}
},
methods:{
toggle:function(){
//切换组件名称
this.cName = this.cName == 'componentA'?'componentB':'componentA';
}
}
});
script>
当点击“切换组件”按钮时,页面内容变化会有一个过渡的效果,结果如下图所示:
实现列表过渡需要使用 v-for 和 transition-group 组件,该组件特点如下所示:
列表过渡的基础用法代码示例如下所示:
<style type="text/css">
/*元素的样式*/
.list-item{
display: inline-block;
margin-right: 10px;
background-color: darkgreen;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
color: aquamarine;
}
/*插入过程和移除过程的过渡效果*/
.num-enter-active,.num-leave-active{
transition: all 1s;
}
/*开始插入,移除结束时的状态*/
.num-enter,.num-leave-to{
opacity: 0;
transform: translateY(30px);
}
style>
<div id="box">
<div>
<button v-on:click="add">插入一个数字button>
<button v-on:click="remove">移除一个数字button>
<transition-group name="num" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
{
{item}}
span>
transition-group>
div>
div>
<script type="text/javascript">
//创建根实例
var vm =new Vue({
el :'#box',
data:{
items:[1,17,8,18,5,20],
nextNum:7
},
methods:{
//生成随机数索引
randomNumber:function(){
return Math.floor(Math.random() * this.items.length)
},
//添加数字
add:function(){
this.items.splice(this.randomNumber(),0,this.nextNum++)
},
//移除数字
remove:function(){
this.items.splice(this.randomNumber(),1)
}
}
});
script>
当单击“插入一个数字”按钮时,会在下方的随机位置插入一个新的数字。当单击“移除一个数字”按钮时,会在下方的随机位置移除一个数字。运行结果如下图所示:
备注:后期会继续跟进 Vue.js前端框架:常用插件,希望大家的多多支持和关注。