17 Vue动画详解

Vue动画

一 使用过渡类名实现过渡

官方文档中说明,Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡

  • 条件渲染 (使用 v-if)
  • 条件展示 (使用 v-show)
  • 动态组件
  • 组件根节点

一个例子:

    <style>
        .slide-fade-enter,
        .slide-fade-leave-to {
            opacity: 0;
        }

        .slide-fade-enter-active {
            transition: all .3s ease;
        }

        .slide-fade-leave-active {
            transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
        }
	</style>
    <div id="app">
        <input type="button" value="toggle" @click="toggle">

        <transition name="slide-fade">
            <h3 id="h3" v-show="flag">{{msg}}</h3>
        </transition>
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                msg: "hello",
                flag: true
            },
            methods: {
                toggle() {
                    this.flag = !this.flag;
                }
            }
        })
    </script>

对于想要使用过渡/动画的Dom元素,使其被包裹于transition标签即可。

在进入/离开过渡时,会有6个class切换:

  • v-enter:进入过渡的开始状态,在元素被插入之前生效,在元素被插入之后的下一帧移除。
  • v-enter-active:定义进入过渡生效的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  • v-enter-to:在元素被插入之后下一帧失效,v-enter被移除,v-enter-to在过渡/动画完成之后移除。
  • v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  • v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  • v-leave-to: 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

Transition Diagram

对于这6个class,如果我们不指定transitionname属性,则v-是默认前缀,如果自定义了name属性,那么v-enter会被替换为transitionname-enter

实现动画时,只需要为这六个class添加样式即可。

二 使用第三方库animate.css实现动画

aninate.css库中包含了许多的常用动画,我们可以使用。

Vue中提供了以下类名,这些类名优先级高于普通类名,使得我们可以优良的结合Vue 的过渡系统和其他第三方 CSS 动画库如animate.css

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

一个使用第三方库animate.css的例子:

<transition 
 enter-active-class="animated tada" 
 leave-active-class="animated bounceOutRight">
  	<p v-show="flag">{{msg}}</p>
</transition>

同时,transition标签还具有:duration属性,可以让我们自定义持续时间,如:

<transition :duration="1000">...</transition>
<transition :duration="{ enter: 500, leave: 800 }">...</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>

首先,我认为有必要说明方法的执行顺序,当一个Dom从无到有,顺序为beforeEnter->enter->afterEnter->beforeLeave->leave->afterLeave,而当一个Dom从有到无,顺序为beforeLeave->leave->afterLeave

下面是一个例子:

<html lang="en">

<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>钩子函数实现动画</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <style>
        /*画个小球*/
        #ball {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background-color: black;
        }
    </style>
</head>

<body>

    <div id="app">
        <input type="button" value="动画开始" @click="flag=!flag">
        <br><br>
        <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"
            v-on:enter-cancelled="enterCancelled" @before-leave="beforeLeave" v-on:leave="leave"
            v-on:after-leave="afterLeave">
            <div id="ball" v-show="flag">
            </div>
        </transition>
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                flag: true,
                msg: "hello"
            },
            methods: {
                beforeEnter(el) {
                    // 设置小球开始动画之前的起始位置
                    console.log("进入beforeEnter...")
                    el.style.opacity = 0;
                    el.style.transform = "translate(0,0)";
                },
                enter(el, done) {
                    console.log("进入enter...")
                    // 不加不行
                    el.offsetWidth
                    // enter表示动画开始之后的样式,可以设置动画后的结束状态
                    el.style.opacity = 1;
                    el.style.transform = "translate(150px,450px)";
                    el.style.transition = "all 1s ease"
                    // 进入afterEnter方法
                    done();
                },
                afterEnter(el, done) {
                    console.log("进入afterEnter...")
                    this.flag = !this.flag;
                },
                enterCancelled(el) {
                    console.log("enterCancelled...")
                },
                beforeLeave(el) {
                    console.log("beforeLeave...")
                },
                leave(el) {
                    console.log("leave...");
                },
                afterLeave(el) {
                    console.log("afterLeave...")
                }
            }
        })

    </script>
</body>

</html>

这个例子展示了一个小球的动画以及执行顺序,大家可以把flag的初始值分别设为truefalse试试。

四 列表动画

列表动画需要使用transition-group属性,且需对每一项添加:key属性。

下面通过一个列表进行实例演示:

<html lang="en">

<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>列表动画</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <style>
        li {
            border: 1px dashed #999;
            line-height: 40px;
            width: 100%;
        }

        li:hover {
            background-color: pink;
            transition: all 0.8s ease;
        }

        .v-enter,
        .v-leave-to {
            opacity: 0;
            transform: translateY(60px);
        }

        .v-enter-active,
        .v-leave-active {
            transition: all 0.6s ease;
        }

        /*v-move指的是元素移动时自动添加的类名*/
        .v-move {
            transition: all 0.6s ease;
        }

        .v-leave-active {
            position: absolute;
        }
    </style>
</head>

<body>

    <div id="app">
        <div class="operation">
            id: <input type="text" v-model="id">
            name: <input type="text" v-model="name">
            <input type="button" value="添加" @click="add">
        </div>
        <transition-group appear tag="ul">
            <li v-for="(per,i) in list" :key="per.id" @click="del(i)">{{per.id}}--{{per.name}}</li>
        </transition-group>

    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                id: "",
                name: "",
                list: [
                    {
                        id: 1, name: "严嵩"
                    },
                    {
                        id: 2, name: "秦桧"
                    },
                    {
                        id: 3, name: "魏忠贤"
                    }
                ]
            },
            methods: {
                add() {
                    this.list.push({
                        id: this.id,
                        name: this.name
                    });
                    this.id = "";
                    this.name = "";
                },
                del(i) {
                    this.list.splice(i, 1)
                }
            }
        })

    </script>
</body>

</html>

在该实例中实现了列表元素添加动画,删除动画。

除此以外,给transition-group添加appear属性可以添加开始入场动画,查看源代码,发现transition-group默认被渲染为span,事实上,我们还可以指定tag属性,实现将其渲染成不同的元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值