当前位置:   article > 正文

Vue 0基础学习路线(11)—— 图解深度详述Vue动画和Vue动画触发条件及Vue动画生命周期、transition 组件、过渡类名及详细案例(附详细案例代码解析过程及版本迭代过程)_vue slidechangetransitionstart监听的activeindex不是由0开始

vue slidechangetransitionstart监听的activeindex不是由0开始怎么回事

1. 重点提炼

  • 动画
    • css
    • js
    • vue
      • 触发条件
        • v-if、v-show、动态组件、根组件
        • css
          - js生命周期

2. 动画

vue 中给组件或元素添加动画的方式可以分为多种,但总体无非还是通过 cssJavaScript 来进行处理

3. CSS

通过 css 添加动画的方式特别的简单,只需要利用 css 中的 transition 就可以做到

<!DOCTYPE html>
<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>Document</title>
    <style>
        .js_animation_box {
            width: 100px;
            height: 100px;
            background: red;
            transition: .5s all;
        }
        .js_animation_box.end {
            width: 200px;
            height: 200px;
            background: green;
        }
    </style>
</head>
<body>
    <button id="js_animation_btn">原生动画</button>
    <div id="js_animation_box" class="js_animation_box"></div>
    <script>
        // 原生 + css
        let jsAnimationBtn = document.querySelector('#js_animation_btn');
        let jsAnimationBox = document.querySelector('#js_animation_box');

        jsAnimationBtn.onclick = function() {
            jsAnimationBox.classList.add('end');
        }
    </script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.44
Branch: branch04

commit description:a1.44(原生css动画demo)

tag:a1.44

(如果不太会css,可参考小迪的blog,有对css详细说明)

3.1 example01

3.1.1 example03-1

vue+css=> 动画

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background: red;
            /*动画效果*/
            transition: all .5s;
        }
        /*移入更改宽*/
        .box:hover {
            width: 200px;
        }
    </style>
</head>
<body>
 
    <div id="app">
        <div class="box"></div>
 
    </div>
 
    <script src="./js/vue.js"></script>
    <script>
        let app = new Vue({
            el: '#app'
        });
    </script>
 
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.45
Branch: branch04

commit description:a1.45(example01-1——vue配合css生成动画)

tag:a1.45

3.1.2 example03-2

融入vue数据操作动画。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background: red;
            /*动画效果*/
            transition: all .5s;
        }
    </style>
</head>
<body>

<div id="app">
    <button @click="fn">按钮</button>
    <div class="box" :style="{width: w}"></div>
</div>

<script src="./js/vue.js"></script>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            w: '100px'
        },
        methods: {
            fn() {
                this.w = '200px';
            }
        }
    });
</script>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.46
Branch: branch04

commit description:a1.46(example01-2——vue配合css生成动画-融入data)

tag:a1.46

3.1.3 example03-3

融入vuedom操作。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background: red;
            /*动画效果*/
            transition: all .5s;
        }
    </style>
</head>
<body>

<div id="app">
    <button @click="fn">按钮</button>
    <div class="box" ref="box1"></div>
</div>

<script src="./js/vue.js"></script>
<script>
    let app = new Vue({
        el: '#app',
        methods: {
            fn() {
                this.$refs.box1.style.width = '200px';
            }
        }
    });
</script>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.47
Branch: branch04

commit description:a1.47(example01-3——vue配合css生成动画-融入dom操作)

tag:a1.47

4. JavaScript

用原生js,引入jQuery去做。

<!DOCTYPE html>
<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>Document</title>
    <style>
        .js_animation_box {
            width: 100px;
            height: 100px;
            background: red;
        }
    </style>
</head>
<body>
    <button id="js_animation_btn">原生动画</button>
    <div id="js_animation_box" class="js_animation_box"></div>
  	<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script>
				// jq
        $('#js_animation_btn').on('click', function() {
            $('#js_animation_box').animate({
                width: 200,
                height: 200
            }, .5);
        });
    </script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.48
Branch: branch04

commit description:a1.48(jq动画demo)

tag:a1.48

5. vue 中的动画处理

vue 中基本和上面的处理方式是一样的

<!DOCTYPE html>
<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>Document</title>
    <style>
        .js_animation_box {
            width: 100px;
            height: 100px;
            background: red;
            transition: .5s all;
        }
        .js_animation_box.end {
            width: 200px;
            height: 200px;
            background: green;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="isEnd = !isEnd">vue动画</button>
        <div :class="['js_animation_box', isEnd ? 'end' : '']"></div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                isEnd: false
            }
        });
    </script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.49
Branch: branch04

commit description:a1.49(vue动画demo)

tag:a1.49

5.1 动画生命周期

vue 为元素和组件的几个特殊的情况提供了对应的处理方式

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

5.1.1 transition 组件

通过 transition 组件包裹的元素或组件,会在上面定义的几个场景中触发过渡,并添加指定的 class 样式。transition会使其下的组件具有动画效果,但是有条件的,在上述四个条件下才(条件渲染、条件展示、动态组件、组件根节点)能触发动画 => 自动帮助添加class,添加class也是有规定的。

参考下方的过渡类名,指定class

5.1.2 过渡类名

  • 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 被删除),在过渡/动画完成之后移除

5.1.3 vue动画深究

Opacity从0运动到1(需要一个这样的动画),Enter代表从无到有的过程(如:v-if为true),这个时候就会有过渡动画(从隐藏到显示),首先会给当前元素添加一个v-enter(动画初始值),紧接着会给它添加v-enter-active(过渡效果),它是设置当前动画的样式,v-enter-to代表目标点(动画终点值),表示即将动画到的终点。

v-enter 在下一帧就自动被销毁了,v-enter-activev-enter-to直到动画完全结束,它们才被自动销毁,这就是它动画的生命周期了。

同理动画离开的时候也是上面的流程,只不过倒过来了。

在这里插入图片描述

5.1.4 example02

5.1.4.1 example02-1

触发v-if演示 => 当 <div class="box" v-if="isShow"></div>隐藏的时候,会自动调用动画,

class名称默认为v-XXX,默认为v-enter-XXXX,前面可以加自己的前缀名(v-),这样自己可以设计多套不同的css样式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background: red;
            /*修改box样式就会触发该动画*/
            transition: all .5s;
        }
    </style>
</head>
<body>

<div id="app">
    <button @click="fn">按钮</button>
    <button @click="isShow=!isShow">{{isShow}}</button>
    <transition>
        <div class="box" v-if="isShow"></div>
    </transition>

</div>

<script src="./js/vue.js"></script>
<script>

    let app = new Vue({
        el: '#app',
        data: {
            isShow: true,
            w: '100px'
        },
        methods: {
            fn() {
                this.$refs.box1.style.width = '200px';
            }
        }
    });

</script>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.50
Branch: branch04

commit description:a1.50(example02-1——transition使用)

tag:a1.50

5.1.4.2 example02-2

存在掉帧,动画效果看得不明显,不能完全看出css效果,再做一个演示:

我们可以为transition组件设置名称属性 => slide-fade

加一些样式效果,再把动画加长至5s

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background: red;
        }

        .slide-fade-enter-active, .slide-fade-leave-active {
            transition: all 5s ease;
        }
        .slide-fade-enter {
            width: 0;
            height: 0;
        }
        .slide-fade-enter-to {
            width: 100px;
            height: 100px;
        }
        .slide-fade-leave {
            /*可以和slide-fade-enter-to合并*/
            width: 100px;
            height: 100px;
        }
        .slide-fade-leave-to {
            /*可以和slide-fade-enter合并*/
            width: 0;
            height: 0;
        }
    </style>
</head>
<body>

<div id="app">
    <button >按钮</button>
    <button @click="isShow=!isShow">{{isShow}}</button>
    <transition name="slide-fade">
        <div class="box" v-if="isShow"></div>
    </transition>

</div>

<script src="./js/vue.js"></script>
<script>

    let app = new Vue({
        el: '#app',
        data: {
            isShow: true
        }
    });

</script>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

触发的时候,会发现class加了很多字符,其实就它会根据动画触发重新渲染的时候,它都会给这个元素添加样式,即加入到class当中。

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a1.51
Branch: branch04

commit description:a1.51(example02-2——transition深入使用)

tag:a1.51

5.1.4.2.1 深入探究

触发动画的时候,class自动追加enter-activeenter-to,运动完成之后又会把这些class给销毁掉。

vue动画组件根据<transition name="slide-fade">,当它包含的元素触发了上面四个条件而重新渲染的时候,它都会触发transition指定的动画,它会给包含的这个元素添加class,然后就会有动画效果了。

需要一个这样的动画,Enter代表从无到有的过程(如:v-iftrue),这个时候就会有过渡动画,首先会给当前元素添加一个.slide-fade-enter(动画初始值=>宽高都是0),紧接着会给它添加.slide-fade-enter-active(过渡效果),它是设置当前动画的样式,.slide-fade-enter-to代表目标点(动画终点值),表示即将动画到的终点。.slide-fade-enter 在下一帧就自动被销毁了,.slide-fade-enter-active.slide-fade-enter-to直到动画完全结束,它们才被自动销毁,这就是它动画的生命周期了。

在这里插入图片描述

同理动画离开的时候也是上面的流程,只不过倒过来了,伴随.slide-fade-leave-active的过渡动画,.slide-fade-leave.slide-fade-leave-to

在这里插入图片描述

6. 小结

很多动画,用css就可以办到,完全没有必要用vue去做,而且transition是有局限性的,它不是任何时候都可以触发的。

假如页面当中已经有一个元素出现了,我想点击一下让它运动到一个位置,这个时候既不会触发v-if,也不会触发v-show,并且不是动态组件,也不是组件根节点。

这个时候动画触发通通无效了,所以操作这种特殊情况,并不是从无到有的过程,所以建议还是用原生js的方式,来加载一些动画库去完成。

通过ref获取dom元素,利用原生js和动画库去完成。(关于原生jscss实现动画,以及调用动画库可参考小迪写的blog

再或者直接使用css去做动画即可。

除此之外,vue动画在动画过程中还会触发动画生命周期,可以参考官方文档(不太重点):

js钩子其实就是在transition当中加一些指定的事件,动画过程中会触发这些指定的事件,执行对应的生命周期函数。可在这些生命周期函数中做些事情,比如改变其样式,添加class,让其动画起来等等。

在这里插入图片描述

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
// ...
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) {
    // ...
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43


(后续待补充)
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号