Vue中使用transition、transition-group实现显示隐藏的过渡动画【开发记录】
前阶段页面涉及到了一些数据的隐藏和显示,数据的新增删除等一些基本的操作,数据的隐藏和显示可以用fadeOut、fadeIn、slideDown、slideUp等动画方法来实现,而数据删除和新增的动画,可以使用transtion和transition-group来实现,之前没怎么用过这两个属性,特此来记录一下使用过程以及遇到的一些小的问题。
1、首先我们先做一些准备工作,先实现一个div的隐藏和显示:
HTML:我们使用template
标签将要显示和隐藏的元素包裹起来,然后使用v-if
进行判断temp
值为true显示,为false即隐藏。点击按钮显示隐藏div。
<template v-if="temp">
<div>这里是你实际需要动态显示或隐藏的内容。</div>
</template>
<button @click="show_temp()">按钮</button>
JS:同时在js中的Vue对象data中声明一个变量做开关用于v-if的判断。
<script type="text/javascript">
var vm = new Vue({
el: "#",
data(){
return {
temp: false,//默认是false即隐藏状态
}
},
show_temp:function(){
if(this.temp) {
this.temp = false;
}else{
this.temp = true;
}
}
});
</script>
上面的代码可以实现基本的点击按钮对div进行显示和隐藏,下面我们在上面的基础上稍加改动为其加上过渡动画效果。
2、transition的使用:
HTML:使用transition标签将需要隐藏的div包裹起来,然后给一个name属性便于对其添加css动画样式。
<transition name="test-slide-fade">
<template v-if="temp">
<div>这里是你实际需要动态显示或隐藏的内容。</div>
</template>
<button @click="show_temp()">按钮</button>
</transition>
CSS:添加动画效果。
.test-slide-fade-enter-active {
transition: all 1s ease;
}
.test-slide-fade-leave-active {
transition: all .5s ease;
}
.test-slide-fade-enter,.test-slide-fade-leave-to{
/* .slide-fade-leave-active 用于 2.1.8 以下版本 */
transform: translateY(10px);
opacity: 0;
}
至此我们已经实现了显示和隐藏的动画效果,上面的css是我自己使用的动画效果,你们可以根据自己的需求来改变,说下transition的属性值。
transition子属性:子属性可以单独的使用,css中直接使用子属性名称并赋值即可。参考文章
第一个参数: all
是 transition-property
属性,有none
| all
| property
;值为none时,没有属性会获得过渡效果,值为all时,所有属性都将获得过渡效果,值为指定的css属性应用过渡效果,多个属性用逗号隔开。
第二个参数: .5
是 transtion-duration
属性,该属性主要用来设置一个属性过渡到另一个属性所需的时间,也就是从旧属性过渡到新属性花费的时间长度,俗称持续时间。
第三个参数: ease
是 tansition-timing-function
属性,该属性值得是过渡的 “缓动函数” ,主要是用来指定浏览器的过渡速度,以及过渡期间的操作进展情况等。
transition-timing-function:linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier(n,n,n,n);
第四个参数: transition-delay
:指定开始出现的延迟时间。我这里没有用到,这个属性值也特别好理解,就不多说了。
3、transition-group的使用:
在使用transition-group之前,简单的说一下和transition的区别,transition主要用作单个元素的隐藏和显示,transition-group通常和v-for一起使用,进行多个元素中的一个元素或者几个元素的新增显示或者删除过程的过渡效果。
JS:这里的site数组实际是你从后台获取的数据,我这里为了演示随便声明了一个。
<script type="text/javascript">
var vm = new Vue({
el: "#",
data(){
return {
sites: []
}
}
});
</script>
HTML:使用div标签进行包裹,使用v-for进行循环出我们展示的数据。
我这里是在一个数组sites中循环出每个site,然后其中有一个删除按钮和两个数组子元素。删除按钮根据index进行元素的删除。
注意:这里要在div中使用v-for不能使用template标签。否则将不会正常显示数据(这是我遇到的一个坑)。
<transition-group>
<div v-for="(site,index) in sites" :key='site.timestamp'>
<img class="" src="" @click="del(index)">
<div>
<template v-for="week in site.weeks">
<div class="">{{week}}</div>
</template>
</div>
<div class="">
<template v-for="time in site.times">
<div class="">{{time}}</div>
</template>
</div>
</div>
</transition-group>
然后使用transition-group标签将整个v-for包裹住。然后千万别忘记加:key属性,没有:key则不会正常显示出所有的数据。
注意:这里的 :key 不能使用index。如果使用index,我们发现在删除的过程中,不会正常显示过渡动画效果,而是每次都是删除最后一个元素,不是我们想要的效果。
这个问题网上有很多提到的,但是都说给唯一字段,后来我想到一个方法自己解决了这个问题。
解决办法:将 :key
属性赋一个唯一字段值,如果我们获取到的后台数据就没有那个唯一字段怎么办呢?
思路:我们可以在刚获取到接口数据时在解析的过程中,使用时间戳作为一个唯一值来使用,但是效果并不是特别的好,因为程序执行的足够快,导致一个循环下来,时间戳都是一样的,实现不了唯一值的效果,后来我做了一个随机的八位数,然后在解析的时候放到自定义属性中封存到每个循环元素的属性中,这样我们可以在设置 :key
时将我们自定义的值作为其属性值,这样就保证它的唯一性。
下面是我的简单代码:获取一个随机十位数存到timetamp
中,然后使用:key ='site.timepamp'
resolverList:function(sites){
if(sites== null || sites== "" || sites== "undefined")return;
for(var i = 0;i<clockList.length;i++){
var site= {};
site["times"] = clockList[i].times.split(",");
site["weeks"] = vm.resolveWeeks(clockList[i].weeks.split(","));
var timestamp = "";
for(var x=0;x<8;x++)timestamp+=Math.floor(Math.random()*8);
site["timestamp"] = timestamp;
vm.sites.push(clock);
}
},
CSS:下面的属性和transition是一样的
.v-enter,.v-leave-to{
transform:translateX(200px);
opacity:0;
}
.v-enter-active,.v-leave-active{
transition: all 0.6s ease;
}
/* 以下代码是成对使用的,删除表格中的某项内容时,避免删除元素后,下一个元素立即进入,没有触发动画效果 */
.v-move{
transition:all 0.6s ease;
}
.v-leave-active{
position:absolute;
}