• Vue.js 动画(三)


    1. Vue 中的动画

    Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
    包括以下工具:

    • 使用过渡类名:使用 transition 元素包裹要设置动画的元素
    • 第三方 CSS 动画库:animate.css
    • 在过渡钩子函数中使用 JavaScript 直接操作 DOM
    • 列表排序过渡:transition-group

    1.1 单元素过渡

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

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

    1.1.1 过渡类名

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

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

    示例:

    h3 元素设置进入退出动画:

    <style>
        /* 自定义两组样式,来控制 transition 内部的元素实现动画 */
        /* v-enter 时间点,元素进入之前的其实状态,此时还未正式进入 */
        /* v-leave-to 时间点,动画离开之后,离开的终止状态,此时,元素动画已结束 */
        .v-enter,
        .v-levae-to {
            opacity: 0;     /*透明度*/
            transform: translateX(150px);       /*元素从 150px 处飘过来,x 轴*/
        }
    
        /* v-enter-active 入场动画的时间段 */
        /* v-levave-active 离场动画的时间段 */
        .v-enter-active,
        .v-levae-activue {
            transition: all 0.8s ease;
        }
    </style>
    
    <body>
        <div id="app">
            <input type="button" value="按钮" @click="flag=!flag">
            <transition>
                <h3 v-if="flag">标题三</h3>
            </transition>
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    flag: false
                },
                methods: {}
            })
        </script>
    </body>
    

    1.1.2 修改过渡类名前缀给多个元素设置动画

    若有多个元素需要设置不同的动画,如果使用同一种过渡类名,那么动画将是一致的,这时就需要修改过渡类名的前缀 + transitionname 属性来实现。

    <style>
        /* 自定义 v 前缀 */
        .my-enter,
        .my-leave-to {
            opacity: 0;
            transform: translateY(70px);        /*从上飞入*/
        }
    
        .my-enter-active,
        .my-leave-active {
            transition: all 0.8s ease;
        }
    </style>
    
    <body>
        <div id="app">
            <input type="button" value="按钮" @click="flag=!flag">
            <transition>
                <h3 v-if="flag">标题三</h3>
            </transition>
    
            <input type="button" value="按钮2" @click="flag2=!flag2">
            <transition name="my">
                <h1 v-if="flag2">标题一</h3>
            </transition>
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    flag: false,
                    flag2: false
                },
                methods: {}
            })
        </script>
    </body>
    

    1.2 第三方 CSS 动画库 animate

    1、导入动画类库:

    <link rel="stylesheet" type="text/css" href="./lib/animate.css">
    

    2、定义 transition 及属性:

    <transition
    	enter-active-class="fadeInRight"
        leave-active-class="fadeOutRight"
        :duration="{ enter: 500, leave: 800 }">
      	<div class="animated" v-show="isshow">动画哦</div>
    </transition>
    

    示例:

    <!DOCTYPE html>
    <html lang="">
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title Page</title>
        <link rel="stylesheet" href="./lib/animate.css">
    </head>
    
    <body>
        <div id="app">
            <input type="button" value="按钮" @click="flag=!flag">
            <!-- 需求: 点击按钮,让 h3 显示,再点击,让 h3 隐藏 -->
            <!-- <transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut">
          <h3 v-if="flag">这是一个H3</h3>
        </transition> -->
    
            <!-- 使用 :duration="毫秒值" 来统一设置 入场 和 离场 时候的动画时长 -->
            <!-- <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="200">
          <h3 v-if="flag" class="animated">这是一个H3</h3>
        </transition> -->
    
            <!-- 使用  :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 src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    flag: false,
                },
                methods: {}
            })
        </script>
    </body>
    
    </html>
    

    参考文档:

    1.3 JavaScript 钩子函数

    可以在属性中声明 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>
    

    JS 中调用:

    // ...
    methods: {
      // --------
      // 进入中
      // --------
    
      beforeEnter: function (el) {
        // ...
      },
      // 当与 CSS 结合使用时
      // 回调函数 done 是可选的
      enter: function (el, done) {
        // ...
        done()
      },
      afterEnter: function (el) {
        // ...
      },
      enterCancelled: function (el) {
        // ...
      },
    
      // --------
      // 离开时
      // --------
    
      beforeLeave: function (el) {
        // ...
      },
      // 当与 CSS 结合使用时
      // 回调函数 done 是可选的
      leave: function (el, done) {
        // ...
        done()
      },
      afterLeave: function (el) {
        // ...
      },
      // leaveCancelled 只用于 v-show 中
      leaveCancelled: function (el) {
        // ...
      }
    }
    

    示例:

    利用 JavaScript 钩子函数实现小球半场动画,模拟加入购物车场景:

    <!DOCTYPE html>
    <html lang="">
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title Page</title>
        <style>
            .ball {
                 15px;
                height: 15px;
                border-radius: 50%;
                background-color: red;
            }
        </style>
    </head>
    
    <body>
        <div id="app">
            <input type="button" value="按钮" @click="flag=!flag">
            <!-- 使用 transition 元素将小球包裹起来 -->
            <transition 
                @before-enter="beforeEnter" 
                @enter="enter" 
                @after-enter="afterEnter">
                <div class="ball" v-show="flag"></div>
            </transition>
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    flag: false,
                },
                methods: {
                    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 这个函数,也就是说:done 是 afterEnter 函数的引用
                    },
                    afterEnter(el) {
                        // 动画完成后,隐藏小球,flag 初始值为 false,点击按钮后为 true,!flag 即为 false
                        this.flag = !this.flag
                    }
                }
            })
        </script>
    </body>
    
    </html>
    

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

    参考文章:

    1.4 列表过渡

    目前为止,关于过渡动画我们已经了解了:

    • 单个节点
    • 同一时间渲染多个节点中的一个

    若要渲染整个列表,使用 <transition-group> 组件,组件特点:

    • <transition-group> 会模块渲染为一个 <span> 标签,若想渲染为其他标签,可以使用 tag 属性更换,如:tag="ul"
    • 内部元素需要提供唯一的 key 属性值
    • CSS 过渡类将会应用在内部元素中,而不是这个组/容器本身

    示例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">
        <style>
            li {
                border: 1px dashed #999;
                margin: 5px;
                line-height: 35px;
                padding-left: 5px;
                font-size: 12px;
                 100%;
            }
    
            li:hover {
                background-color: hotpink;
                transition: all 0.8s ease;
            }
    
            /* 过渡开始状态,以及进入过渡的结束状态 */
            .v-enter,
            .v-leave-to {
                opacity: 0;
                transform: translateY(80px);
            }
    
            /* 进入过渡生效时的状态,离开过渡生效时的状态 */
            .v-enter-active,
            .v-leave-active {
                transition: all 0.6s ease;
            }
    
            /* 下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果 */
            .v-move {
                transition: all 0.6s ease;
            }
    
            .v-leave-active {
                position: absolute;
            }
        </style>
    </head>
    
    <body>
        <div id="app">
            <div class="col-md-8">
                <div>
                    <label>
                        Id:
                        <input type="text" v-model="id">
                    </label>
    
                    <label>
                        Name:
                        <input type="text" v-model="name" @keyup.enter="add">
                    </label>
    
                    <input type="button" value="添加" @click="add">
                </div>
    
                <!-- 使用 transition-group 包裹要过渡的列表 -->
                <!-- v-for 循环创建元素,设置动画,且必须为每一个元素设置 :key 属性 -->
                <!-- 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>
    
            </div>
    
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <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>
    </body>
    
    </html>
    

    参考文章:

  • 相关阅读:
    Django之url路由
    Django之setting文件
    Diango之通过form表单向服务端发送数据
    Django之win7下安装与命令行工具
    Linux学习之查看系统资源命令总结(二十二)
    实现简单的web框架
    Linux下发送邮件
    Linux学习之日志管理(二十一)
    Shell学习之结合正则表达式与通配符的使用(五)
    Linux学习之后台任务与定时任务(二十)
  • 原文地址:https://www.cnblogs.com/midworld/p/13611037.html
Copyright © 2020-2023  润新知