当需要渲染整个列表,就需要使用 transition-group
官网上显示的列表过渡与单元素过渡的区别
示例
效果图
示例代码
<template>
<div>
<button @click="show = !show"> clcik </button>
<transition-group >
<div v-if="show" key="word">hello word</div>
<div v-if="show" key="text">hello text</div>
</transition-group>
</div>
</template>
<script>
export default {
data(){
return{
show:false,
}
}
}
</script>
<style scoped>
.v-enter,
.v-leave-to{
opacity: 0;
transform: translate(30px);
}
.v-enter-active,
.v-leave-active{
transition: all .3s ;
}
.v-enter-to,
.v-leave {
opacity: 1;
transform: translate(0);
}
</style>
列表的排序过渡
transition-group
组件中提供啦一个新特性:v-move ,它会在元素改变定位的过程中使用
内部的实现:Vue 使用了一个叫 FLIP 简单的动画队列,使用 transforms 将元素从之前的位置平滑过渡新的位置。
需要注意的是使用 FLIP 过渡的元素不能设置为 display: inline 。作为替代方案,可以设置为 display: inline-block 或者放置于 flex 中。
示例
没有设置v-move的效果 设置v-move效果
区别在排序的效果中
源码
<template>
<div>
<button @click="handleAdd">添加</button>
<button @click="handleDelete">删除</button>
<button @click="handleShuffle">排序</button>
<transition-group tag="ul">
<li v-for="li in list" :key="li"> {{ li }}</li>
</transition-group>
</div>
</template>
<script>
export default {
data(){
return{
list:[1,2,3,4,5,6,7,8,9],
nextNum:10,
}
},
methods:{
handleAdd(){
this.nextNum ++;
let index = this.rendomIndex()
this.list.splice(index,0,this.nextNum);
},
handleDelete(){
let index = this.rendomIndex()
this.list.splice(index,1)
},
rendomIndex(){
return Math.floor(Math.random() * this.list.length);
},
handleShuffle(){
this.list.sort(() => Math.random() - 0.5 )
}
}
}
</script>
<style scoped>
ul,li{
list-style: none;
display: block;
}
button{
display: block;
margin: 10px auto;
}
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(30px);
}
.v-enter-active,
.v-leave-active{
transition: all .3s;
}
.v-leave,
.v-enter-to{
opacity: 1;
transform: translateX(0);
}
.v-move{
transition: all .3s;
}
</style>
案例
关键字搜索
效果图
<template>
<div>
关键字搜索
<input type="text" v-model="value">
<transition-group tag="ul">
<li v-for="li in computedLists" :key="li.name">{{ li.name }}</li>
</transition-group>
</div>
</template>
<script>
export default {
data(){
return {
value:'',
lists:[
{name:'zhangsan'},
{name:'lisi'},
{name:'wangwu'},
{name:'liumang'},
{name:'pangzi '},
]
}
},
computed:{
computedLists(){
return this.lists.filter(ele => ele.name.includes(this.value) )
}
}
}
</script>
<style scoped>
ul,li{
list-style: none;
}
li {
height: 24px;
}
.v-enter,
.v-leave-to {
opacity: 0;
height: 0px;
}
.v-leave-active,
.v-enter-active {
transition: all .3s;
}
.v-enter-to,
.v-leave {
opacity: 1;
height: 24px;
}
</style>
关键字搜索使用js钩子实现
<template>
<div>
关键字搜索
<input type="text" v-model="value">
<transition-group
tag="ul"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
>
<li v-for="li in computedLists" :key="li.name">{{ li.name }}</li>
</transition-group>
</div>
</template>
<script>
export default {
data(){
return {
value:'',
lists:[
{name:'zhangsan'},
{name:'lisi'},
{name:'wangwu'},
{name:'liumang'},
{name:'pangzi '},
]
}
},
computed:{
computedLists(){
return this.lists.filter(ele => ele.name.includes(this.value) )
}
},
methods:{
beforeEnter(el){
el.style.opacity = 0;
el.style.height = 0;
},
enter(el,done){
Velocity(el,{
opacity:1,
height:'24px'
},{
duration:300,
complete:done
})
},
leave(el,done){
Velocity(el,{
opacity:0,
height:'0px',
},{
duration:300,
complete:done
})
}
}
}
</script>
<style scoped>
ul,li{
list-style: none;
}
li {
height: 24px;
}
</style>