动画与组件

动画有三种:

1.animate类库

2.css过渡(transition组件)(列表动画)

3.js钩子函数(transition组件)

1.animate类库(要下载包:https://daneden.github.io/animate.css/

CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。

我们可以通过以下特性来自定义过渡类名:

  • enter-class
  • enter-active-class
  • enter-to-class (2.1.8+)
  • leave-class
  • leave-active-class
  • leave-to-class (2.1.8+)

他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。

注意:animated不是animate

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="animate.css-master/animate.css">

</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
    <button @click="flag = !flag">Toggle </button>
    <!--<transition-->
            <!--name="custom-classes-transition"-->
            <!--enter-active-class="animated flipIn"-->
            <!--leave-active-class="animated bounceOutRight"-->
            <!--:duration="{ enter: 200, leave: 800 }">-->
        <!--<p v-if="flag">hello</p>-->
    <!--</transition>-->

    <!--简写方法-->
    <transition
            name="custom-classes-transition"
            enter-active-class=" flipIn"
            leave-active-class=" bounceOutRight"
            :duration="{ enter: 200, leave: 800 }">
        <p v-if="flag"class="animated" >hello</p>
    </transition>
</div>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            flag:true
        },
        methods:{

        }
    })

</script>
</body>
</html>

2.css过渡(transition组件)

过渡的类名

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。(transition)

  3. v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。

  4. v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。(transition)

v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
         /*进入的时候*/
        .slide-fade-enter-active {
            transition:all 0.3s ease;
        }
         /*离开的时候*/
           .slide-fade-leave-active {
               transition:all 0.8s ease;
           }

        .slide-fade-enter, .slide-fade-leave-to{
            transform:translateX(160px);
            opacity:0;
        }

         /*进入的时候*/
         .v-enter-active {
             transition:all 0.3s ease;
         }
         /*离开的时候*/
         .v-leave-active {
             transition:all 1s ease;
         }

         .v-enter, .v-leave-to{
             transform:translateX(160px);
             opacity:0;
         }
    </style>
</head>
<body>
    <script src="vue-2.4.0.js"></script>
    <div id="app">
        <button @click="flag = !flag">Toggle </button>
        <transition name="slide-fade">
            <p v-if="flag">hello</p>
        </transition>
        <hr>
        <!--不给transition name时,默认为v- -->
        <button @click="flag1 = !flag1">默认的Toggle </button>
        <transition>
            <p v-if="flag1">hello</p>
        </transition>
    </div>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{
                flag:true,
                flag1:true
            },
            methods:{

            }
        })

    </script>
</body>
</html>

 列表动画

在dom中transition-group显示为span标签

    appear属性:实现页面刚展示出来的时候,入场的效果
    tag属性:指定transition-group这个元素在浏览器中渲染为指定的元素,
    如果不添加tag属性,那么页面自动将该标签渲染为span标签

 

v-move

     列表的进入/离开过渡,对列表直接操作(增、删)的元素,封装<transition-group>并按常规的CSS或JS过渡即可;但在操作这些元素的位置变化时,由于DOM文档流的变化,会同时引起其它(邻近)节点元素的位置变化,例如在列表插入一个<li>,插入点原本的<li>会下移,删除一个<li>,下面的<li>会上移补充占据这个位置。
 对于这些“被动”移动的元素来说,也可以实现过渡,这就用到了v-move 特性。

<div id="app">
    <!--appear属性:实现页面刚展示出来的时候,入场的效果
    tag属性:指定transition-group这个元素在浏览器中渲染为指定的元素,
    如果不添加tag属性,那么页面自动将该标签渲染为span标签-->
    <!--<ul>-->
        <transition-group appear tag="ul">
            <li @click="del(index)" v-for="(item,index) in list" :key="item">{{item}}</li>
        </transition-group>
    <!--</ul>-->
</div>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            msg:'我要猎杀那些黑暗中的人',
            list: [1,2,3,4,5,6,7,8,9]
        },
        methods:{
            del(i){
                this.list.splice(i,1);
            }
        }
    })

3.js钩子函数(transition组件)

可以在属性中声明 JavaScript 钩子

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

 

注意:当只用 JavaScript 过渡的时候,enterleave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。

推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        p{
            background-color: red;
            display: inline-block;
            border-radius: 50%;
        }
    </style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
    <button @click="flag = !flag">Toggle </button>
    <transition
        v-on:before-enter="beforeEnter"
        v-on:enter="enter"
        v-on:after-enter="afterEnter"
    >
        <p v-show="flag">hello</p>
    </transition>
</div>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            flag:false
        },
        methods:{
            beforeEnter:function (el) {
                el.style.transform = 'translateX(0)';
            },
            enter:function (el,done) {     /*当与css结合时 done时可选的*/
                el.offsetLeft;
                el.style.transform = 'translateX(150px)';
                el.style.transition = 'all 2s ease ';
                done();
            },
            afterEnter:function (el) {
                this.flag = !this.flag;
                // el.style.transform = 'translateX(150px)';
                // el.style.transition = 'all 2s ease ';
                // opacity = 1;
            }
        }
    })

</script>
</body>
</html>

创建组件:通过 Vue component(‘组件名’,{})

注意一定要以-的形式命名(w3c规则)

Vue。component(‘com-1’{

template:‘’                                                 注意:<transition>中一定要有一个根元素div

})

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        p{
            background-color: red;
            display: inline-block;
            border-radius: 50%;
        }
        #template div h1{
            color: red;
        }
    </style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
    <my-com1></my-com1>
    <my-com2></my-com2>
    <my-com3></my-com3>
    <my-com4></my-com4>
    <my></my>
</div>
<template id="template">
    <div>
        <h1 style="color: red"> 这是我通过外部template来创建的组件,不能写外联样式???????</h1>
        <h1 style="color: red"> template标签在div外面</h1>
    </div>
</template>

<!--//注意组件template里面一定要有标签-->
<template id="template2"><h1>这是私有组件</h1></template>
<script>
    // 使用Vue.extend来创建全局组件
    var com1 = Vue.extend({
        // 通过template属性,指定了组件要展示的html解构
        template: '<h1>这是用Vue.extend创建的组件</h1>'
    });
    Vue.component('my-com1',com1);


    Vue.component('my-com2',Vue.extend({
        // 通过template属性,指定了组件要展示的html解构
        template: '<h2>这是用Vue.extend创建的第二种写法组件</h2>'
    }));

    Vue.component('my-com3',{
        // 通过template属性,指定了组件要展示的html解构
        template: '<h3>这是用Vue.extend创建的第3种写法组件</h3>'
    });

    Vue.component('my-com4',{
        // 通过template属性,指定了组件要展示的html解构
        template: '<div><h4>这是用Vue.extend创建的第3种写法组件</h4> <h4>这是我在后面加的第二个h4,必须要加根元素</h4></div>'
    });

    Vue.component('my-com4',{
        // 通过template属性,指定了组件要展示的html解构
        template: '#template'
    });


    var vm = new Vue({
        el:'#app',
        data:{
            flag:false
        },
        methods:{},
        components:{
            my :{
                template: '#template2'
            }
    }
    })

</script>
</body>
</html>

注意:组件定义一个data -----------一定要是方法,且return一个对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        p{
            background-color: red;
            display: inline-block;
            border-radius: 50%;
        }
    </style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
    <login-a></login-a>
</div>

<script>
    // 组件中可以由自己的data数据,data必须是方法,且必须返回一个对象,data数据必须只能在template中{{}},不能再app总{{}}
    Vue.component('login-a',{
        template:'<h3>这是一个全局的简化的组件===={{msg}}</h3>',
        data: function () {    //必须是方法,且必须返回一个对象
            return {msg:'这是我通过我创建的组件来创建的data,它是一个方法,并且返回的是一个对象'}
        }
    });
    var vm = new Vue({
        el:'#app',
        data:{
            flag:false
        },
        methods:{},
        components:{
            my :{
                template: '#template2'
            }
        }
    })

</script>
</body>
</html>

也可以定义methods(例如创建一个计数组件)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        p{
            background-color: red;
            display: inline-block;
            border-radius: 50%;
        }
    </style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
    <counter></counter>
    <hr>
    <counter></counter>
    <hr>
    <counter></counter>
    <hr>
    <counter></counter>
    <hr>
    <counter></counter>
</div>
<template id="count">
    <div>
        <button @click="add">+1</button>
        <h3>{{count}}</h3>
    </div>
</template>

<script>
    // 组件中可以由自己的data数据,data必须是方法,且必须返回一个对象,data数据必须只能在template中{{}},不能再app总{{}}
    Vue.component('counter',{
        template:'#count',
        data:function () {
            return {count:0}      /*这里不能用变量,否则调用的同一个对象*/
        },
        methods:{
            add(){
                this.count++;
            }
        }
    });
    var vm = new Vue({
        el:'#app',
        data:{
            flag:false
        },
        methods:{}
    })

</script>
</body>
</html>

组件切换(v-if或者component)

<component :is="flag"></component>
 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        p{
            background-color: red;
            display: inline-block;
            border-radius: 50%;
        }
        .v-renter,.v-leave-to{
            opacity: 0;
            transform: translate(150px);
        }
        .v-leave-active,.v-enter-active{
            transition: all 2s ease;
        }
    </style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
    <!--<button @click="flag=true">登录</button >-->
    <!--<button @click="flag=false">注册</button>-->
    <!--<login v-if="flag"></login>-->
    <!--<register v-else="flag"></register>-->

    <button @click="flag='login'">登录</button >
    <button @click="flag='register'">注册</button>

    <transition mode="out-in">      <!--如果不添加mode="out-in",那么,点击按钮时切换下一个组件和上一个组件动画同时进行-->
        <component :is="flag"></component>
    </transition>
</div>
<script>
    // 组件中可以由自己的data数据,data必须是方法,且必须返回一个对象,data数据必须只能在template中{{}},不能再app总{{}}
    Vue.component('login',{
        template:'<h1>登录组件</h1>'
    });
    Vue.component('register',{
        template:'<h1>注册组件</h1>'
    });
    var vm = new Vue({
        el:'#app',
        data:{
            // flag:true
            flag:'login'
        },
        methods:{}
    })

</script>
</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值