Vue的动画与Vue双向绑定
- 这两个问题的讲解,我通过一个小小的列表动画案例来进行,这样效果会比较好点。
顾名思义,列表动画,我们首先要创建一个列表。
使用指令:v-for=""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../lib/vue-2.5.17/vue.js"></script>
<style>
li{
border: 1px dashed #999;
margin: 5px;
line-height: 35px;
padding-left: 5px;
font-size: 12px;
}
li:hover{
background-color: yellow;
transition: all 0.8s ease;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item,i) in list" :key="item.id">
{{item.id}} --- {{item.name}}
</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
list:[
{id: 1,name: '第一'},
{id: 2,name: '第二'},
{id: 3,name: '第三'},
{id: 4,name: '第四'},
]
},
methods: {}
});
</script>
</html>
- 通过一些简单的代码,我们在页面上渲染出来了一个列表.
- 话不多说,开始划知识点。
知识点一:Vue双向绑定及事件绑定
要给一个列表增加项和删除项,我们需要用的就是——Vue的双向绑定和事件绑定。
在页面上写一个增加按钮,删除操作我们就直接通过点击li
进行列表项的删除。
使用到的指令v-model
,v-on简写'@'
- 使用Vue的双向绑定通过指令
v-model
来实现。 v-bind
也能实现数据的绑定,但是只能实现数据的单向绑定。- 同时,Vue的双向绑定只针对于表单元素,对其他元素不适用。
双向绑定小案例:
<div id="app">
<h4>{{msg}}</h4>
<input type="text" style="width:100%" v-model="msg">
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'大家都是好学生,爱敲代码,爱学习,爱思考,简直是完美,没瑕疵!'
},
methods:{}
});
</script>
我们把双向绑定的思想移植到我们的列表中,实现列表的增加和删除。
<body>
<div id="app">
<div>
<label for="">
Id:
<input type="text" v-model="id">
</label>
<label for="">
Name:
<input type="text" v-model="name">
</label>
<input type="button" @click="add" value="添加">
</div>
<ul>
<li v-for="(item,i) in list" :key="item.id" @click="del(i)">
{{item.id}} --- {{item.name}}
</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
list:[
{id: 1,name: '第一'},
{id: 2,name: '第二'},
{id: 3,name: '第三'},
{id: 4,name: '第四'},
]
},
methods: {
add() {
this.list.push({id: this.id,name: this.name})
this.id = this.name = ''
},
del(i){
this.list.splice(i,1);
}
}
});
</script>
至此,我们就实现了列表的添加和删除,但是这样的添加和删除给人一种僵硬之感,如果我们带上一些简单的过渡动画效果,就又是另一种感觉。
知识点二:Vue的动画
Vue的动画也是通过一组指令来实现的。
.v-enter
定义进入过渡的开始状态.v-enter-active
定义进入过渡生效时的状态.v-enter-to
定义进入过渡的结束状态.v-leave
定义离开过渡的开始状态.v-leave-active
定义离开过渡生效时的状态.v-leave-to
定义离开过渡的结束状态
这六个指令代表了六种动画状态,其中1和6状态是相同的。3和4状态是相同的,2和5代表状态的过渡。
我们设置一组动画,让列表进行增加操作时,让新来的项从下面缓慢的出现,删除时再缓慢的消失。
.v-enter,.v-leave-to{
opacity: 0;
transform: translateY(80px);
}
.v-enter-active,.v-leave-active{
transition: all 0.6s ease;
}
- 加上这一组样式之后,你会发现动画效果并没有出现,那是因为,Vue中规定,使用动画的元素要使用
transition
或transition-group
标签进行包裹。 - 看到这两个标签的名字,我想我们就知道了他们的不同,
transition
包裹的是单个动画元素,而transition-group
包裹的是一组动画元素。 - 所以我们还需要把列表中的
li
标签使用transition-group
包裹起来。
<ul>
<transition-group>
<li v-for="(item,i) in list" :key="item.id" @click="del(i)">
{{item.id}} --- {{item.name}}
</li>
</transition-group>
</ul>
- 这样我们让列表在添加和删除时动了起来,但是还有一个问题:
在进行删除时,被删除元素下面的元素会一直等待前面元素的删除操作完成,删除完成之后,下面的元素会一下子跑到被删除者的位置。
对于这样的情况,我们在设想中应该是上面的元素在删除的同时,下面的元素开始缓慢的向上移动。
如果达到这样的效果?我们还需要一组样式:
.v-move{
transition: all 0.6s ease;
}
.v-leave-active{
position: absolute;
}
.v-move
和.v-leave-active
配合使用能够实现列表后续元素渐渐地漂上来的效果。
- 解决了删除突然移动的问题,新的问题又随之而来,那就是使用
position: absolute;
的问题:
使用绝对定位,元素脱标会导致元素在删除的时候,宽度会变成元素本身的真实宽度。
解决方法:我们通过样式,手动设置li
的宽度为width:100%
。
知识点三:transition-group
的appear
和tag
属性
看似完美的列表的动画背后,其实还隐藏这一个严重的问题。
打开浏览器控制台,把代码一级一级的展开,我们就会发现如图所示的问题:
标签的嵌套不符合w3c的规范,我们不能在一个行级元素下嵌套块级元素。
当然,对单个动画元素包括的transition
标签则没有此类问题。
我们没有写<span></span>
标签,是从哪里来的呢?答案呼之欲出,没错就是transition-group
的问题!!!
此时我们给transition-group
加上一个tag
属性,指定为ul
,同时删除我们自己写的ul
标签:
<!-- <ul> -->
<transition-group tag="ul">
<li v-for="(item,i) in list" :key="item.id" @click="del(i)">
{{item.id}} --- {{item.name}}
</li>
</transition-group>
<!-- </ul> -->
这样我们再次展开代码时,就会发现,代码的嵌套关系是正确,transition-group
渲染成了ul
标签。
由此我们知道:
通过为 transition-group
元素设置 tag
属性,指定为 transition-group
渲染为指定的元素,如果不指定tag
属性,transition-group
默认渲染为span
标签 。
至此,我们才算是解决了列表动画中的所有问题。
那么我在知识点中写的appear
有什么作用呢?我们可以先加上看一下效果:
<transition-group appear tag="ul">
<li v-for="(item,i) in list" :key="item.id" @click="del(i)">
{{item.id}} --- {{item.name}}
</li>
</transition-group>
没错,给transition-group
添加 appear
属性,实现的是页面刚展示出来的时候的入场效果。
以上,就是对Vue双向绑定和Vue动画的讲解了。