Vue列表过渡
2017-08-22 22:24
423 查看
前面的话
本文将详细介绍Vue列表过渡概述
前面分别介绍了单元素CSS过渡和JS过渡,以及多元素过渡。如何同时渲染整个列表呢?在这种情景中,需要使用<transition-group>组件【<transition-group>】
<transition-group>不同于
<transition>, 它会以一个真实元素呈现:默认为一个
<span>。也可以通过
tag特性更换为其他元素。而且其内部元素总是需要提供唯一的
key属性值
<transition-group name="list" tag="p"> <!-- ... --> </transition-group>
普通过渡
下面是一个添加和删除列表项的例子<style> .list-item {display: inline-block;margin-right: 10px;} .list-enter-active, .list-leave-active {transition: all 1s;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>
<div id="list-demo" class="demo"> <button @click="add">Add</button> <button @click="remove">Remove</button> <transition-group name="list" tag="p"> <span v-for="item in items" :key="item" class="list-item">{{item}}</span> </transition-group> </div>
<script> new Vue({ el: '#list-demo', data: { items: [1,2,3,4,5,6,7,8,9], nextNum: 10 }, methods: { randomIndex() { return Math.floor(Math.random() * this.items.length) }, add() { this.items.splice(this.randomIndex(), 0, this.nextNum++) }, remove() { this.items.splice(this.randomIndex(), 1) }, } }) </script>
平滑过渡
上面这个例子有个问题,当添加和移除元素的时候,周围的元素会瞬间移动到他们的新布局的位置,而不是平滑的过渡【v-move】
<transition-group>组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的
v-move特性,它会在元素的改变定位的过程中应用。像之前的类名一样,可以通过
name属性来自定义前缀,也可以通过
move-class属性手动设置
在上面代码中基础上,做出如下改进:
1、增加.list-move的样式,使元素在进入时实现过渡效果
2、在.list-leave-active中设置绝对定位,使元素在离开时实现过渡效果
<style> .list-item {display: inline-block;margin-right: 10px;} .list-move,.list-enter-active, .list-leave-active {transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>
变换过渡
下面接着利用move属性,进行变换过渡,即一个列表中的列表项既不增加也不减少,只是不断地变换其位置<style> .list-move{transition: transform 1s;} </style>
<div id="list-demo" class="demo"> <button @click="shuffle">shuffle</button> <transition-group name="list" tag="ul"> <li v-for="item in items" :key="item">{{item}}</li> </transition-group> </div>
<script> new Vue({ el: '#list-demo', data: { items: [1,2,3,4,5,6,7,8,9], }, methods: { shuffle(){ this.items = this.items.sort(()=>{return Math.random() - 0.5;}) }, } }) </script>
下面的效果看起来很神奇,内部的实现,Vue 使用了一个叫 FLIP 简单的动画队列,使用 transforms 将元素从之前的位置平滑过渡新的位置
下面将进入离开的例子和这个技术结合, 使列表的一切变动都会有动画过渡
[注意]使用 FLIP 过渡的元素不能设置为
display: inline。作为替代方案,可以设置为
display: inline-block或者放置于 flex 中
<style> .list-item {display: inline-block;margin-right: 10px;} .list-move,.list-enter-active, .list-leave-active {transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>
以上代码中,由于move、enter和leave都需要设置transition。因此,直接在元素上设置transition即可
<style> .list-item {display: inline-block;margin-right: 10px;transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>
下面是完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style> .list-item {display: inline-block;margin-right: 10px;transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>
</head>
<body>
<div id="list-demo" class="demo">
<button @click="shuffle">shuffle</button>
<button @click="add">Add</button>
<button @click="remove">Remove</button>
<transition-group name="list" tag="p">
<span v-for="item in items" :key="item" class="list-item">{{item}}</span>
</transition-group>
</div>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script>
<script>
new Vue({
el: '#list-demo',
data: {
items: [1,2,3,4,5,6,7,8,9],
nextNum: 10
},
methods: {
randomIndex() {
return Math.floor(Math.random() * this.items.length)
},
add() {
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove() {
this.items.splice(this.randomIndex(), 1)
},
shuffle(){
this.items = this.items.sort(()=>{return Math.random() - 0.5;})
},
}
})
</script>
</body>
</html>
多维列表
FLIP 动画不仅可以实现单列过渡,多维网格的过渡也同样简单<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .container {width: 270px;margin-top: 10px;line-height:30px;text-align:center;} .cell {display: inline-block;width: 30px;height: 30px;outline: 1px solid #aaa;} .cell-move {transition:1s;} </style> </head> <body> <div id="list-demo" class="demo"> <button @click="shuffle">shuffle</button> <transition-group name="cell" tag="div" class="container"> <span v-for="cell in cells" :key="cell.id" class="cell">{{ cell.number }}</span> </transition-group> </div> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script> <script> new Vue({ el: '#list-demo', data: { cells: Array.apply(null, { length: 81 }) .map(function (_, index) { return { id: index, number: index % 9 + 1 } }) }, methods: { shuffle(){ this.cells = this.cells.sort(()=>{return Math.random() - 0.5;}) }, } }) </script> </body> </html>
渐进过渡
通过 data 属性与 JavaScript 通信 ,就可以实现列表的渐进过渡下面是使用CSS过渡实现的一个例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .list-move,.list-enter-active, .list-leave-active {transition: 1s;} .list-leave-active{position:absolute;} .list-enter,.list-leave-to{opacity: 0;height:0;} </style> </head> <body> <div id="list-demo" class="demo"> <input v-model="query"> <transition-group name="list" tag="ul"> <li v-for="(item, index) in computedList" :key="item" :data-index="index">{{item}}</li> </transition-group> </div> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script> <script> new Vue({ el: '#list-demo', data: { query: '', list: ['HTML','CSS','Javascript','jQuery','Vue'] }, computed: { computedList() { return this.list.filter((item)=>{ return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1 }) } }, }) </script> </body> </html>
上面的效果中,列表项是一齐运动的。如果要实现依次运动的效果,则需要使用JS过渡来实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="list-demo" class="demo"> <input v-model="query"> <transition-group name="list" tag="ul" :css="false" @before-enter="beforeEnter" @enter="enter" @leave="leave"> <li v-for="(item, index) in computedList" :key="item" :data-index="index">{{item}}</li> </transition-group> </div> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/velocity.min.js"></script> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script> <script> new Vue({ el: '#list-demo', data: { query: '', list: ['HTML','CSS','Javascript','jQuery','Vue'] }, computed: { computedList() { return this.list.filter((item)=>{ return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1 }) } }, methods: { beforeEnter(el) { el.style.opacity = el.style.height = 0 }, enter(el, done) { setTimeout(()=>{ Velocity(el,{ opacity: 1, height: '1.6em' },{ complete: done }) }, el.dataset.index * 150) }, leave(el, done) { setTimeout(()=>{ Velocity(el,{ opacity: 0, height: 0 },{ complete: done }) }, el.dataset.index * 150) } }, }) </script> </body> </html>
相关文章推荐
- vue 过渡效果-列表过渡
- [Vue][V-move]列表进入/离开的平滑过渡,官方教程学习释疑
- Vue列表过渡
- 详解Vue学习笔记进阶篇之列表过渡及其他
- vue学习07--进入/离开&列表过渡
- Vue列表过渡
- vue transition-group 列表过渡
- Vue.js学习笔记:过渡效果(含列表过渡)
- vue 列表选中 v-for class
- vue中v-for循环列表根据条件判断两边对齐效果(常用)
- Vuejs——(1)入门(单向绑定、双向绑定、列表渲染、响应函数)
- 【Vue】 -(6) 条件渲染和列表渲染
- 详解Vue结合后台的列表增删改案例
- vue调用百度地图API输入提示示例下拉列表一直被触发问题
- vue通过滚动行为实现从列表到详情,返回列表原位置的方法
- vue 封装自定义组件--tabal列表编辑单元格组件
- Vue相关(过渡动画)
- Vue基础之Vue列表渲染
- 学习前端js核心Vue 之 directives(自定义命令) transition (过渡动画 js) 个人备忘笔记
- vue动态删除从数据库倒入列表的某一条方法