Vue的动画与Vue双向绑定

82 篇文章 7 订阅

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的动画也是通过一组指令来实现的。

  1. .v-enter 定义进入过渡的开始状态
  2. .v-enter-active 定义进入过渡生效时的状态
  3. .v-enter-to 定义进入过渡的结束状态
  4. .v-leave 定义离开过渡的开始状态
  5. .v-leave-active 定义离开过渡生效时的状态
  6. .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中规定,使用动画的元素要使用transitiontransition-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-groupappeartag属性

看似完美的列表的动画背后,其实还隐藏这一个严重的问题。

打开浏览器控制台,把代码一级一级的展开,我们就会发现如图所示的问题:
嵌套问题截图
标签的嵌套不符合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动画的讲解了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值