# 3. 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">
    <script src="./lib/vue/vue.js"></script>
    <title>Vue-动画-使用过度类名实现动画</title>
    <!-- 2. 自定义两组样式,来控制 transition 内部的元素实现动画 -->
    <style>
        /* v-enter 是进入之前,元素的起始状态,此时还没有开始进入 */
        /* v-leave-to 是动画离开之后,离开的终止状态,此时元素动画已经结束了 */
        .v-enter,
        .v-leave-to {
            opacity: 0;
            transform: translateX(150px)
        }

        /* v-enter-active 【入场动画的时间段】 */
        /* v-leave-active 【离场动画的时间段】 */
        .v-enter-active,
        .v-leave-active {
            transition: all 0.8s ease;
        }

        /* =======自定义前缀======== */
        .qm-enter,
        .qm-leave-to {
            opacity: 0;
            transform: translateY(150px)
        }

        /* v-enter-active 【入场动画的时间段】 */
        /* v-leave-active 【离场动画的时间段】 */
        .qm-enter-active,
        .qm-leave-active {
            transition: all 0.8s ease;
        }

    </style>
</head>

<body>
    <div id="app">
        <!-- 需求:点击按钮,让h3 显示,再点击,让h3 隐藏 -->
        <input type="button" value="显示/隐藏" @click="show=!show">
        <!-- 1. 使用 transition 元素,把需要被动画控制的元素,包裹起来 -->
        <transition>
            <h3 v-if="show">这是一个有动画的H3</h3>
        </transition>
        <h3 v-if="show">这是一个H3</h3>

        <hr>
            
        <!-- 自定义前缀 -->
        <input type="button" value="显示/隐藏" @click="show2=!show2">
        <!-- 使用name对前缀进行自定义 -->
        <transition name="qm">
            <h4 v-if="show2">这是一个有动画的H4</h4>
        </transition>

    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            show: false,
            show2: false
        },
        methods: {

        }
    })
</script>

</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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

# 使用第三方库实现动画

示例

<!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">
    <script src="./lib/vue/vue.js"></script>
    <title>Vue-动画-使用第三方CSS库实现动画</title>
    <!-- 使用第三方CSS库实现动画 -->
    <!-- 官网地址:https://daneden.github.io/animate.css/ -->
    <link rel="stylesheet" href="./lib/css/animate.css">
</head>

<body>
    <div id="app">
        <!-- 需求:点击按钮,让h4 显示,再点击,让h4 隐藏 -->
        <input type="button" value="显示/隐藏" @click="show=!show">
        <!-- 使用 :duration="毫秒值" 类统一控制 入场 和 出场 时候的动画时长 -->
        <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="1000">
            <h4 v-if="show" class="animated">1.这是一个有动画的H4</h4>
        </transition>
        <!-- 使用 :duration="{enter: 200, leave: 400}" 来分别设置 入场 和 出场 时候的动画时长 -->
        <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="{ enter: 200, leave: 400 }">
            <h4 v-if="show" class="animated">2.这是一个有动画的H4</h4>
        </transition>
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            show: false
        },
        methods: {}
    })
</script>

</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

# 使用钩子函数实现半场动画

<!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">
    <script src="./lib/vue/vue.js"></script>
    <title>Vue-动画-使用钩子函数实现半场动画</title>
    <style>
        .ball {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background-color: blue;
        }
    </style>
</head>

<body>
    <div id="app">
        <input type="button" value="快到碗里来" @click="show = !show">
        <!-- 使用 :duration="毫秒值" 类统一控制 入场 和 出场 时候的动画时长 -->
        <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
            <div v-show="show" class="ball"></div>
        </transition>
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            show: false
        },
        methods: {
            // 动画钩子函数的第一个参数是 el,表示要执行动画的元素节点,原生的js DOM 对象。
            // el 是通过 document.getElementById('') 方式获取到的原生js DOM 对象。
            beforeEnter(el) {
                // beforeEnter 表示动画入场之前
                // 开始动画之前的起始样式
                el.style.transform = "translate(0, 0)"
            },
            enter(el, done) {
                // 这句话,没有实际的作用,但是如果不写,出不来动画效果。
                el.offsetWidth
                // enter 表示动画开始之后的样式
                el.style.transform = "translate(150px, 750px)"
                el.style.transition = "all 1000ms ease"
                // done 是一个函数的引用
                // 这里的done 就是 afterEnter 这个函数
                done()
            },
            afterEnter(el) {
                // 直接控制属性来隐藏掉show
                this.show = !this.show
            }
        }
    })
</script>

</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
61

# 列表过度动画

列表动画使用vue为我们提供的 transition-group 标签实现列表的过度动画效果。

下面的例子中使用了一些css样式

  • transform - 属性应用于元素的2D或3D转换。这个属性允许你将元素旋转,缩放,移动,倾斜等。
  • transition - 属性设置元素当过渡效果。
  • opacity - 透明级别
<!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">
    <script src="./lib/vue/vue.js"></script>
    <title>Vue-列表动画</title>
    <style>
        /* li的基本样式 */
        .qm-li {
            border: 1px dashed #999;
            margin: 5px;
            line-height: 35px;
            padding-left: 5px;
            font-size: 14px;
            width: 100%;
        }

        /* 设置鼠标进入时的动画 */
        li:hover {
            background-color: hotpink;
            transition: all 0.4s ease;
        }

        /* 设置进入时和退出后的状态 */
        .qm-enter,
        .qm-leave-to {
            opacity: 0;
            transform: translateY(80px)
        }

        /* 设置在运动过程中的效果 */
        .qm-enter-active,
        .qm-leave-active {
            transition: all 0.6s ease;
        }

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

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

<body>
    <div id="app">
        <label>
            id:
            <input type="text" v-model="id">
        </label>
        <label>
            name:
            <input type="text" v-model="name">
        </label>
        <input type="button" value="添加" @click="add">

        <!-- <ul> -->
            <!-- 在实现列表过度的时候,如果需要过度额元素,是通过 v-for 循环出来的 -->
            <!-- 不能使用transition包裹,需要使用 transition-Group -->
            <!-- 如果要为 v-for 循环创建的元素设置动画,必须为每一个元素设置:key属性 -->
            <!-- 注意,使用 transition 相当于渲染出来一个span标签-->
            <!-- appear使该ul进场时增加动画效果,tag可以使当前的标签变为自定义的标签 -->
            <transition-group name='qm' appear tag="ul">
                <li class="qm-li" v-for="(item,i) in list" :key="item.id" @click="del(i)">
                    {{item.id}} --- {{item.name}}
                </li>
            </transition-group>
        <!-- </ul> -->
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            id: null,
            name: '',
            list: [
                { id: 1, name: '我爱罗' },
                { id: 2, name: '宇智波斑' },
                { id: 3, name: '佩恩' }
            ]
        },
        methods: {
            add() {
                this.list.push({ id: this.id, name: this.name })
            },
            del(index) {
                this.list.splice(index, 1);
            }
        }
    })
</script>

</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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
最近更新: 2019/10/17 上午4:20:42