前言

前面写了几篇关于Vue使用transition对于单个元素的动画示例,那么如果要对于列表这样多个元素的,是无法使用​​transition​​来包裹实现动画的。

那么按照官网的介绍就要使用​​transition-group​​来实现,下面来看看一个列表动画的效果。

介绍说明

​列表过渡​

目前为止,关于过渡我们已经讲到:

  • 单个节点
  • 同一时间渲染多个节点中的一个

那么怎么同时渲染整个列表,比如使用 ​​v-for​​​ ?在这种场景中,使用 ​​<transition-group>​​ 组件。在我们深入例子之前,先了解关于这个组件的几个特点:

  • 不同于​​<transition>​​​,它会以一个真实元素呈现:默认为一个​​<span>​​​。你也可以通过​​tag​​attribute 更换为其他元素。
  • ​过渡模式​​不可用,因为我们不再相互切换特有的元素。
  • 内部元素总是需要提供唯一的​​key​​ 属性值。
  • CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身。

​列表的进入/离开过渡​

现在让我们由一个简单的例子深入,进入和离开的过渡使用之前一样的 CSS 类名。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 1.导入vue.js库 -->
<script src="lib/vue.js"></script>

<style>
/*设置列表的样式*/
.list-item {
display: inline-block;
margin-right: 10px;
}
/*设置列表transition-group的name为list的入场以及离场动画效果*/
.list-enter-active, .list-leave-active {
transition: all 1s;
}
.list-enter, .list-leave-to
/* .list-leave-active for below version 2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}
</style>
</head>
<body>

<div id="app">

<!-- 设置一个添加按钮 -->
<button v-on:click="add">Add</button>
<!-- 设置一个删除按钮 -->
<button v-on:click="remove">Remove</button>

<!-- 使用tag指定包括的元素为P标签,命名为list -->
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</span>
</transition-group>

</div>

<script>
// 2\. 创建一个Vue的实例
var vm = new Vue({
el: '#app',
data: {
items: [1,2,3,4,5,6,7,8,9],
nextNum: 10
},
methods:{
randomIndex: function () {
// 通过获取items列表中的随机下标
return Math.floor(Math.random() * this.items.length)
},
add: function () {
// 在列表items随机位置下标,设置0为不删除数据,添加this.nextNum++的数据
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function () {
// 随机删除列表中的其中一个数据
this.items.splice(this.randomIndex(), 1)
},
}
})
</script>

</body>
</html>

浏览器显示如下:


35. Vue使用transition-group实现列表动画_vue.js

image-20200202152713519 35. Vue使用transition-group实现列表动画_数据_02

image-20200202152734467

那么点击Add或者Remove都有对应的动画效果。

这个例子有个问题,当添加和移除元素的时候,周围的元素会瞬间移动到他们的新布局的位置,而不是平滑的过渡,我们下面会解决这个问题。


35. Vue使用transition-group实现列表动画_数据_03

image-20200202153305901 35. Vue使用transition-group实现列表动画_vue.js_04

image-20200202153339091

​列表的排序过渡 v-move​

​<transition-group>​​ 组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的 ​v-move​​ attribute,它会在元素的改变定位的过程中应用。像之前的类名一样,可以通过 ​​name​​​ 属性来自定义前缀,也可以通过 ​​move-class​​ 属性手动设置。

注意:​​v-move​​​ 需要和​​v-leave-active​​结合使用,示例如下:


35. Vue使用transition-group实现列表动画_数据_05

image-20200202153922470

实现效果如下:


35. Vue使用transition-group实现列表动画_vue.js_06

image-20200202154139274

设置列表的appear初始化动画

在最后当页面初始刷新的时候,还可以对列表中的元素进行动画过渡,设置​​appear​​属性即可,如下:


35. Vue使用transition-group实现列表动画_html_07

image-20200202154456403

再次刷新浏览器,查看列表的初始动画效果,如下:


35. Vue使用transition-group实现列表动画_vue.js_08

image-20200202154549639

动态效果如下:

 

35. Vue使用transition-group实现列表动画_html_09

 

完整示例代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 1.导入vue.js库 -->
<script src="lib/vue.js"></script>

<style>
/*设置列表的样式*/
.list-item {
display: inline-block;
margin-right: 10px;
}
/*设置列表transition-group的name为list的入场以及离场动画效果*/
.list-enter-active, .list-leave-active {
transition: all 1s;
}
.list-enter, .list-leave-to
/* .list-leave-active for below version 2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}

/* 下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地移动过来的效果 */
.list-move {
transition: all 0.6s ease;
}
.list-leave-active{
position: absolute;
}
</style>
</head>
<body>

<div id="app">

<!-- 设置一个添加按钮 -->
<button v-on:click="add">Add</button>
<!-- 设置一个删除按钮 -->
<button v-on:click="remove">Remove</button>

<!-- 使用tag指定包括的元素为P标签,命名为list -->
<transition-group name="list" tag="p" appear>
<span v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</span>
</transition-group>

</div>

<script>
// 2\. 创建一个Vue的实例
var vm = new Vue({
el: '#app',
data: {
items: [1,2,3,4,5,6,7,8,9],
nextNum: 10
},
methods:{
randomIndex: function () {
// 通过获取items列表中的随机下标
return Math.floor(Math.random() * this.items.length)
},
add: function () {
// 在列表items随机位置下标,设置0为不删除数据,添加this.nextNum++的数据
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function () {
// 随机删除列表中的其中一个数据
this.items.splice(this.randomIndex(), 1)
},
}
})
</script>

</body>
</html>


35. Vue使用transition-group实现列表动画_数据_10