今天看啥  ›  专栏  ›  Merbng

Vue学习:动画

Merbng  · 简书  ·  · 2019-05-20 17:07

动画:使用过度类名实现动画

  • v-enter
    这是一个时间点,是进入之前,元素的起始状态,此时还没有开始进入
  • v-leave-to
    是一个时间点,是动画离开之后,离开的终止状态,此时 元素 动画已经结束了
  • .v-enter-active
    入场动画的时间段
  • .v-leave-active
    离场动画的时间段

可自定义前缀

给transition 添加一个name属性
<transition name="my">

<style>
        .my-enter, my-leave-to {
            opacity: 0;
            transform: translateY(70px);
        }

        .my-enter-active,
        my-leave-active {
            transition: all 0.8s ease;
        }
</style>

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/vue-2.4.0.js"></script>
    <style>
        .v-enter, v-leave-to {
            opacity: 0;
            transform: translateY(150px);
        }
        .v-enter-active,
        .v-leave-active {
            transition: all 0.8s ease;
        }
    </style>
</head>
<body>
<div class="app">
    <input type="button" value="切换" @click="flag=!flag">
    <transition>
        <h3 v-if="flag">测试啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</h3>
    </transition>
</div>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            flag: false
        },
        methods: {}
    })
</script>
</body>
</html>

案例:vue-resource改造品牌列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/vue-2.4.0.js"></script>
    <script src="lib/vue-resource-1.3.4.js"></script>
    <link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">

</head>
<body>
<div class="app">

    <div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">添加品牌</h3>
    </div>
    </div>
    <div class="panel-body form-inline">
        <label >Name
        <input type="text" name="" class="form-control" v-model="name">
        </label>
        <input type="button" value="添加" class="btn btn-primary" @click="add">
    </div>

    <table class="table table-bordered table-hover table-striped">
        <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Ctime</th>
            <th>Operation</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="item in list" :key="item.id">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.ctime}}</td>
            <td>
                <a href="" @click.prevent="del(item.id)">删除</a>
            </td>
        </tr>
        </tbody>
    </table>
</div>
<script>
    Vue.http.options.root = 'http://vue.studyit.io/';
    Vue.http.options.emulateJSON = true;
    var vm = new Vue({
        el: '.app',
        data: {
            name: '',
            /*存放所有品牌列表的数组*/
            list: [],
            msg: '这是内容啊',
            methods: {
                getAllList() {
                    this.$http.get('api/getprodlist').then(result => {
                        this.result = result.body;
                        if (result.status === 0) {
                            this.list = result.message;
                        } else {
                            alert("获取数据失败!")
                        }
                    })
                },
                add() {
                    this.$http.post('api/addproduct', {name: this.name}).then(result => {
                        if (result.body.status === 0) {
                            this.getAllList();
                            this.name = '';
                        } else {
                            alert("添加失败!")
                        }
                    })
                },
                del(id) {
                    this.$http.get('api/delproduct/' + id).then(result => {
                        if (result.body.status === 0) {
                            this.getAllList();
                        } else {
                            alert("添加失败!")
                        }
                    })
                }
            }
        },
        methods: {}
    })
</script>
</body>
</html>

使用第三方类实现动画

  • 使用:duration="毫秒值"来统一设置 入场 和 离场 时候的动画时长
  • 使用:duration={enter:200,leave:400} 来分别设置入场的时长 和 离场 的时长
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="lib/animate.css">
    <script src="lib/vue-2.4.0.js"></script>
</head>
<body>
<div class="app">
    <input type="button" value="动画" @click="flag=!flag">
    <!--使用:duration="毫秒值" 来统一设置 入场 和 离场 时候的动画时长-->
    <!--使用:duration={enter:200,leave:400} 来分别设置入场的时长 和 离场 的时长-->
    <transition
            enter-active-class="bounceIn"
            leave-active-class="bounceOut"

            :duration="{enter:200,leave:400}"
    >
        <h3 v-if="flag" class="animated">动画动画动画动画动画动画动画</h3>
    </transition>
</div>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            flag: false
        },
        methods: {}
    })
</script>
</body>
</html>

案例:使用钩子函数模拟小球半场动画

  • 注意:动画钩子函数的第一个参数:el 表示要执行动画的那个DOM元素,是个原生的JS DOM对象

  • beforeEnter
    表示动画入场之前,此时,动画尚未开始,可以 在 beforeEnter 中,设置元素开始动画之前的起始样式

  • enter
    表示动画 开始之后的样式,这里,可以设置小球完成动画之后的,结束状态

  • afterEnter
    动画完成之后,会调用 afterEnter

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/vue-2.4.0.js"></script>
    <style>
        .ball {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background-color: red;
        }
    </style>

</head>
<body>
<div class="app">
    <input type="button" value="购物车" @click="flag=!flag">
    <transition
            @before-enter="beforeEnter"
            @enter="enter"
            @after-enter="afterEnter"
    >
        <div class="ball" v-show="flag"></div>
    </transition>
</div>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            flag: false
        },
        methods: {
            //注意:动画钩子函数的第一个参数:el 表示要执行动画的那个DOM元素,是个原生的JS DOM对象
            beforeEnter(el) {
          //设置小球开始动画之前的,起始位置
                el.style.transform = 'translate(0,0)'
            },
            enter(el, done) {
                // 这句话,没有实际的作用,但是,如果不写,出不来动画效果;
                // 可以认为 el.offsetWidth 会强制动画刷新
                el.offsetWidth;
                el.style.transform = 'translate(150px,450px)';
                el.style.transition = 'all 1s ease';
                done()
            },
            afterEnter(el) {
                // 动画完成之后,会调用 afterEnter
                // console.log('ok')
                this.flag = !this.flag
            }
        }
    })
</script>
</body>
</html>

列表动画

  • 在实现列表过渡的时候,如果需要过渡的元素,是通过 v-for 循环渲染出来的,不能使用 transition 包裹,需要使用 transitionGroup
  • 如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性
  • ransition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果
  • 通过 为transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/vue-2.4.0.js"></script>
    <style>
        li {
            border: 1px dashed #999;
            margin: 5px;
            line-height: 35px;
            padding-left: 5px;
            font-size: 12px;
            width: 100%;
        }

        li:hover {
            background-color: hotpink;
            transition: all 0.8s ease;
        }
        .v-enter,
        .v-leave-to {
            opacity: 0;
            transform: translateY(80px);
        }

        /* 下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果 */
        .v-move {
            transition: all 0.6s ease;
        }
        .v-leave-active{
            position: absolute;
        }

    </style>
</head>
<body>
<div class="app">
    <div>
        <label>ID:
            <input type="text" v-model="id">
        </label>
        <label>Name
            <input type="text" v-model="name">
        </label>
        <input type="button" value="添加" @click="add">
    </div>
    <!--给transition-group 添加appear 属性, 实现 页面刚展示出来的时候 入场时候的效果-->
    <!--通过给transition-group元素 设置tag属性,指定 transition-group 渲染为指定的元素,如果不指定tag属性,默认渲染span标签-->
    <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>
</div>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            id: '',
            name: '',
            list: [{id: 1, name: '测试'}, {id: 2, 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>



原文地址:访问原文地址
快照地址: 访问文章快照