3

Vue过渡和动画效果展示(案例、GIF动图演示、附源码) - 智博程序园

 2 years ago
source link: https://www.cnblogs.com/zbcxy506/p/note_1vue-05.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Vue过渡和动画效果展示(案例、GIF动图演示、附源码)

本篇随笔主要写了Vue过渡和动画基础、多个元素过渡和多个组件过渡,以及列表过渡的动画效果展示。详细案例分析、GIF动图演示、附源码地址获取。

作为自己对Vue过渡和动画效果知识的总结与笔记。

因内容有案例解读,代码实现,导致篇幅稍长,大约3分钟可以浏览完,如有需要的话(请笔友耐心看完,也可按目录查找所需内容)

如需要全部案例代码:请到文章末尾获取(百度网盘链接,全套案例源码

案例实现模版:

PS: 点击模版后的 -->  这个标志可以浏览目录结构,以便快速定位需要的内容

以下案例均是基于此模版实现的(以第一个案例为例)

效果展示:

2769248-20220425192238968-2099720940.gif

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 
 4 <head>
 5     <meta charset="UTF-8">
 6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 7     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 8     <title>Document</title>
 9     <!-- 此处为引用JS、CSS等文件区、且css,文件与html文件在同一目录下 -->
10     <script src="velocity.js"></script>
11     <script src="vue.js"></script>
12     <script src="velocity.min.js"></script>
13     <script src="lodash.js"></script>
14     <script src="lodash.min.js"></script>
15 
16     <link rel="stylesheet" href="animate.css">
17     <link rel="stylesheet" href="animate.min.css">
18 
19     <!-- 此处为样式引用 -->
20     <style>
21         /* 图形的初始状态 */
22         .chart {
23             width: 200px;
24             height: 50px;
25             background-color: orange;
26         }
27 
28         /* 进入和离开的过程 */
29         .box-enter-active,
30         .box-leave-active {
31             transition: width 3s;
32             /* width的变化,动画时间是3秒 */
33         }
34 
35         /* 进入初始状态 和 离开的结束状态*/
36         .box-enter,
37         .box-leave-to {
38             width: 0px;
39         }
40 
41         /* 进入的结束状态 和 离开的初始状态 */
42         .box-enter-to,
43         .box-leave {
44             width: 200px;
45         }
46     </style>
47 </head>
48 
49 <body>
50 
51     <!-- 此处为主代码区 -->
52     <div id="app">
53         <button @click="toggle">改变图形宽度</button>
54         <transition name="box">
55             <div class="chart" v-if="show"></div>
56         </transition>
57     </div>
58     <script>
59         var vm = new Vue({
60             el: '#app',
61             data: {
62                 show: true,
63             },
64             methods: {
65                 toggle() {
66                     this.show = !this.show   // 每次都取反
67                 }
68             }
69         })
70     </script>
71 
72 </body>
73 
74 </html>

一、Vue过渡和动画基础

1.什么是过渡和动画

过渡,简而言之,就是从一个状态向另外一个状态插入值,新的状态替换了旧的状态。

通过<transition>标签搭配CSS动画(如@keyframes)可以实现动画效果。动画相比过渡来说,动画可以在一个声明中设置多个状态,例如,可以在动画20%的位置设置一个关键帧,然后在动画50%的位置设置一个完全不同的状态。另外,<transition>标签还提供了一些钩子函数,可以结合JavaScript代码来完成动画效果。

(1)代码:

 1   <style>
 2     /* 图形的初始状态 */
 3     .chart {
 4       width: 200px;
 5       height: 50px;
 6       background-color: orange;
 7     }
 8     /* 进入和离开的过程 */
 9     .box-enter-active, .box-leave-active {
10       transition: width 3s;  /* width的变化,动画时间是3秒 */
11     }
12     /* 进入初始状态 和 离开的结束状态*/
13     .box-enter, .box-leave-to {
14       width: 0px;
15     } 
16     /* 进入的结束状态 和 离开的初始状态 */
17     .box-enter-to, .box-leave {
18       width: 200px;
19     }
20   </style>
21   <script src="vue.js"></script>
22 </head>
23 <body>
24   <div id="app">
25     <button @click="toggle">改变图形宽度</button>
26     <transition name="box">
27       <div class="chart" v-if="show"></div>
28     </transition>
29   </div>
30   <script>
31     var vm = new Vue({
32       el: '#app',
33       data: {
34         show: true,
35       },
36       methods: {
37         toggle () {
38           this.show = !this.show   // 每次都取反
39         }
40       }
41     })
42  </script>

(2)效果展示:

2769248-20220425192409292-627663651.gif

2.transition组件

Vue为<transition>标签内部的元素提供了3个进入过渡的类和3个离开过渡的类,

过渡类型

说明

v-enter

进入过渡的开始状态,作用于开始的一帧

v-enter-active

进入过渡生效时的状态,作用于整个过程

v-enter-to

进入过渡的结束状态,作用于结束的一帧

v-leave

离开过渡的开始状态,作用于开始的一帧

v-leave-active

离开过渡生效时的状态,作用于整个过程

v-leave-to

离开过渡的结束状态,作用于结束的一帧

上表中6个CSS类名在进入和离开的过渡中切换的存在周期如下图所示:

2769248-20220425123703362-2068095412.png

3.自定义类名

Vue中的transition组件允许使用自定义的类名。如果使用自定义类名,则不需要给<transition>标签设置name属性。自定义类名是通过属性来设置的,具体属性如下。

  • 进入:enter-class、 enter-active-class、 enter-to-class
  • 离开:leave-class、 leave-active-class、 leave-to-class

自定义类名的优先级高于普通类名,所以能够很好地与其他第三方CSS库结合使用。 animate.css是一个跨浏览器的CSS3动画库,它内置了很多经典的CSS3动画,使用起来很方便。接下来,我们将通过animate.css动画库来演示自定义类名的使用。

(1)实现步骤:

  • 下载并引入animate.css动画库

首先从官方网站获取animate.css文件,保存到文件目录中。其次创建html文件,并在文件中引入animate.css文件

  • 编写HTML结构代码

animated是基本的类名,bounceInLeft是动画的类名

  • 编写JavaScript代码

(2)代码:

 1 <div id="app">
 2     <button @click="show=!show">显示/隐藏</button>
 3     <transition enter-active-class="animated bounceInLeft"
 4      leave-active-class="animated bounceOutLeft">
 5       <p v-if="show">过渡文字效果</div>
 6     </transition>
 7   </div>
 8   <script>
 9     var vm = new Vue({
10       el: '#app',
11       data: { show: true }
12     })
13  </script>

注意:

动画效果都是在事件处理方法中控制的,在元素初始渲染时(页面刚打开时)并没有动画效果。可以通过给transition组件设置appear属性来给元素添加初始渲染的动画效果。

(3)效果展示:

2769248-20220425192618796-61790713.gif

 1  <div id="app">
 2     <button @click="show=!show">显示/隐藏</button>
 3     <transition appear appear-active-class="animated swing"
 4      enter-active-class="animated bounceIn"
 5      leave-active-class="animated bounceOut">
 6       <div v-if="show">过渡文字效果</div>
 7     </transition>
 8   </div>
 9   <script>
10     var vm = new Vue({ el: '#app', data: { show: true } })
11   </script>

上述代码中,appear表示开启此特性,appear-class表示初始class样式,appear-to-class表示过渡完成的class样式,appear-active-class会应用在整个过渡过程中。

(3)效果展示:

2769248-20220425192630872-1373196470.gif

4.使用@keyframes创建CSS动画

(1)实现步骤:

@keyframes规则创建动画,就是将一套CSS样式逐步演变成另一套样式,在创建动画过程中,可以多次改变CSS样式,通过百分比或关键词from和to(等价于0%和100%)来规定动画的状态。

(2)代码:

 1   <style>
 2     div.circular {
 3       width: 100px;
 4       height: 100px;
 5       background: red;
 6       border-radius: 50%;
 7       margin-top: 20px;
 8       text-align: center;
 9       line-height: 100px;
10       color: #fff;
11     }
12     .bounce-enter-active {
13       animation: Ami .5s;
14     }
15     .bounce-leave-active {
16       animation: Ami .5s;
17     }
18     @keyframes Ami {
19       0% {transform: scale(0); background: red;}
20       20% {transform: scale(1); background: burlywood;}
21       50% {transform: scale(1.5); background: blueviolet;}
22       100% {transform: scale(1); background: burlywood;}
23     }
24   </style>
25   <script src="vue.js"></script>
26 </head>
27 <body>
28   <div id="app">
29     <button @click="show=!show">使用@keyframes创建CSS动画</button>
30     <transition name="bounce">
31       <div class="circular" v-if="show">圆形</div>
32     </transition>
33   </div>
34   <script>
35     var vm = new Vue({ el: '#app', data: { show: true } })
36   </script>

(3)效果展示:

2769248-20220425192707269-269175573.gif

5.钩子函数实现动画

(1)实现步骤:

在<transition>标签中定义了一些动画钩子函数,用来实现动画。钩子函数可以结合CSS过渡(transitions)、动画(animations)使用,还可以单独使用。

(2)代码:

 1  <div id="app">
 2     <transition
 3       @before-enter="beforeEnter"
 4       @enter="enter"
 5       @after-enter="afterEnter"
 6       @enter-cancelled="enterCancelled"
 7       @before-leave="beforeLeave"
 8       @leave="leave"
 9       @after-leave="afterLeave"
10       @leave-cancelled="leaveCancelled"
11       v-bind:css="false">
12     </transition>
13   </div>
14   <script>
15     // 具体案例演示可以参考demo15.html
16     var vm = new Vue({
17       el: '#app',
18       methods: {
19         // beforeEnter入场钩子
20         // 动画入场之前,此时动画尚未开始,设置元素开始动画之前的起始样式
21         beforeEnter (el) {},
22         // enter用于设置动画开始之后的样式 
23         enter (el, done) { 
24           // ...
25           done()
26         },
27         // 在入场动画完成之后会调用
28         afterEnter (el) {},
29         enterCancelled (el) {},
30         // 出场钩子
31         beforeLeave (el) {},
32         leave (el, done) {
33           // ...
34           done()
35         },
36         afterLeave (el) {}, 
37         leaveCancelled (el) {},
38       }
39     })
40   </script>

6.Vue结合Velocity.js实现动画

(1)实现步骤:

  • 下载并引入velocity.min.js文件

首先从官方网站获取velocity.min.js文件,保存到文件目录中。其次创建html文件,并在文件中引入velocity.min.js文件

  • 编写HTML结构代码

beforeEnter和enter两个入场动画函数,leave是出场动画函数

  • 编写JavaScript代码

(2)示例代码:

 1  <div id="app">
 2     <button @click="show=!show">动画效果</button>
 3     <transition @before-enter="beforeEnter" @enter="enter"
 4      @leave="leave" v-bind:css="false">
 5       <p v-if="show">文字动画效果</p>
 6     </transition>
 7   </div>  
 8   <script>
 9     var vm = new Vue({
10       el: '#app',
11       data: {
12         show: false,
13       },
14       methods: {
15         beforeEnter (el) {
16           el.style.opacity = 0                      // 透明度为0
17           el.style.transformOrigin = 'left'    // 设置旋转元素的基点位置
18           el.style.color = 'red'                    // 颜色为红色
19         },
20         enter (el, done) {            // duration动画执行时间
21           Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
22           Velocity(el, { fontSize: '1em' }, { complete: done })
23         },
24         leave (el, done) {
25           Velocity(el, { translateX: '15px', rotateZ: '50deg' },
26           {duration: 3000})
27           Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
28           Velocity(el, { rotateZ: '45deg', translateY: '30px', translateX: '30px', opacity: 0}, { complete: done } )
29         }
30       }
31     })
32   </script>

(3)效果展示:

2769248-20220425192754464-655885472.gif

二、多个元素过渡

1.不同标签名元素过渡

(1)实现步骤:

不相同标签名元素可以使用v-if和v-else来进行过渡

(2)代码:

 1 <div id="app">
 2     <transition>
 3       <ul v-if="items.length > 0">
 4         <li>项目1</li>
 5         <!-- 项目... -->
 6       </ul>
 7       <p v-else>抱歉,没有找到您查找的内容。</p>
 8     </transition>
 9   </div>  
10   <script>
11     var vm = new Vue({ el: '#app', data: { items: [] } })
12   </script>

(3)效果展示:

2769248-20220425192814601-1986768338.png

2.相同标签名元素过渡

当有相同标签名的元素切换时,需要通过key特性设置唯一值来标记,从而让Vue区分它们,因为Vue为了效率只会替换相同标签中的内容。下面通过案例演示当有相同标签名button时,使用v-if和v-else设置key值来实现切换。

(1)实现步骤:

  • 给同一个元素的key属性设置不同的状态来代替v-if和v-else。
  • 使用多个v-if结合key属性来实现相同标签名的过渡效果。
  • 代码是使用的v-if条件语进行判断的,在这里使用computed计算属性来监控变量show的变化,在页面上进行数据绑定来展示结果

(2)代码:

案例一:使用v-if和v-else设置key值来实现切换

 1  <div id="app">
 2     <button @click="isEditing = !isEditing">切换保存和编辑按钮</button>
 3     <div>
 4       <transition name="fade">
 5         <button v-if="isEditing" key="save">保存</button>
 6         <button v-else key="edit">编辑</button>
 7       </transition>
 8     </div>
 9   </div>
10   <script>
11     var vm = new Vue({
12       el: '#app',
13       data: { isEditing: true }
14     })
15   </script>

案例二:同一个元素的key属性设置不同的状态来代替v-if和v-else

 1   <div id="app">
 2     <button @click="isEditing = !isEditing">切换保存和编辑按钮</button>
 3     <div>
 4       <transition name="fade">
 5         <button v-bind:key="isEditing">
 6           {{isEditing ? '保存' : '编辑'}}
 7         </button>
 8       </transition>
 9     </div>
10   </div>
11   <script>
12     var vm = new Vue({ el: '#app', data: { isEditing: true } })
13   </script>

(3)效果展示:

2769248-20220425192908497-250192968.gif

案例三:使用多个v-if结合key属性来实现相同标签名的过渡效果

 1 <style>
 2     .row-enter { width: 0px; }
 3     .row-enter-active { transition: width 3s;  }
 4     .row-enter-to{ width: 200px; }
 5     .red { background: red; height: 20px; }
 6     .blue { background: blue; height: 20px;  }
 7     .yellow { background: yellow; height: 20px;  }
 8   </style>
 9   <script src="vue.js"></script>
10 </head>
11 <body>
12   <div id="app">
13     <button @click="showNum">切换</button>
14     <div>
15       <transition name="row">
16         <div class="red" v-if="show == 'A'" key="A"></div>
17         <div class="blue" v-if="show == 'B'" key="B"></div>
18         <div class="yellow" v-if="show == 'C'" key="C"></div>
19       </transition>
20     </div>
21   </div>
22   <script>
23   var vm = new Vue({
24     el: '#app',
25     data: { show: 'A' }, // 初始化show的值为A
26     methods: {
27       showNum () {
28         if (this.show == 'A') {
29           return this.show = 'B'
30         } else if (this.show == 'B') {
31           return this.show = 'C'
32         } else {
33           return this.show = 'A'
34         }
35       }
36     }
37   })
38   </script>

(3)效果展示:

2769248-20220425192941059-2096954477.gif

3.过渡模式

新旧两个元素参与过渡的时候,新元素的进入和旧元素的离开会同时触发,这是因为<transition>的默认行为进入和离开同时发生了。如果要求离开的元素完全消失后,进入的元素再显示出来(如开关的切换),可以使用transition提供的过渡模式mode,来解决当一个组件离开后,另一个组件进来时发生的位置的闪动或阻塞问题。

(1)实现步骤:

过渡模式的原理是,设置有序的过渡而不是同时发生过渡。在transition中加入mode属性,它的两个值如下所示。

  1. in-out 表示新元素先进行过渡,完成之后当前元素过渡离开
  2. out-in表示当前元素先进行过渡,完成之后新元素过渡进入

使用out-in实现开关的切换过渡效果。

(2)代码:

 1  <style>
 2     .fade-enter, .fade-leave-to { opacity: 0; }
 3     .fade-enter-active, .fade-leave-active { transition: opacity .5s; }
 4   </style>  
 5   <script src="vue.js"></script>
 6 </head>
 7 <body>
 8   <div id="app">
 9     <transition name="fade" mode="out-in">
10       <button :key="isOff" @click="isOff = !isOff">{{isOff ? 'Off' : 'On'}}</button>
11     </transition>
12   </div>
13   <script>
14     var vm = new Vue({ el: '#app', data: { isOff: false } })
15   </script>

(3)效果展示:

2769248-20220425193026732-1567389465.gif

三、多个组件过渡

1.什么是多个组件过渡

多个组件之间的过渡,只需要使用动态组件即可,动态组件需要通过Vue中的<component>元素绑定is属性来实现多组件的过渡。接下来通过案例演示如何实现多个组件的过渡。

2.案例演示

(1)实现步骤:

  • 定义登录组件
  • 编写CSS代码
  • 编写JS代码

(2)代码:

 1 <style>
 2     .fade-enter-active, .fade-leave-active {
 3       transition: opacity .5s ease;
 4     }
 5     .fade-enter, .fade-leave-to {
 6       opacity: 0;
 7     }
 8   </style>  
 9   <script src="vue.js"></script>
10 </head>
11 <body>
12   <!-- 定义登录组件 -->
13   <template id="example1">
14     <span>我是登录组件</span>
15   </template>
16   <!-- 定义注册组件 -->
17   <template id="example2">
18     <span>我是注册组件</span>
19   </template>
20   <div id="app">
21     <a href="javascript:;" @click="compontentName='example1'">登录</a>
22     <a href="javascript:;" @click="compontentName='example2'">注册</a>
23     <transition name="fade" mode="in-out">
24       <component :is="compontentName"></component>
25     </transition>
26   </div>
27   <script>
28     Vue.component('example1', {template: '#example1'})
29     Vue.component('example2', {template: '#example2'})
30     var vm = new Vue({
31       el: '#app',
32       data: { compontentName: '' }
33     })
34   </script>

(3)效果展示:

2769248-20220425193048706-1820844954.gif

四、列表过渡

1.什么是列表过渡

列表过渡,需要使用v-for和transition-group组件来实现。

transition-group组件会以一个真实元素呈现,在页面中默认渲染成<span>标签,可以通过tag属性来修改,如<transition-group tag="div">渲染出来就是div标签。

注意:列表的每一项都需要进行过渡,列表在循环时要给每一个列表项添加唯一的key属性值,这样列表才会有过渡效果。在进行列表过渡时,过渡模式不可用,因为不再互相切换特有的元素。

2.列表的进入和离开过渡

(1)实现步骤:

  • 一个简单的案例讲解列表过渡,通过name属性自定义CSS类名前缀,来实现进入和离开的过渡效果。
  • 在浏览器中打开,查看页面效果。单击“随机插入一个数字”,单击“随机移除一个数字”按钮,效果如下图所示。

(2)代码:

 1 <style>
 2     /* 数字圆圈样式 */
 3     .list-item {
 4       display: inline-block;
 5       margin-right: 10px;
 6       background-color: red;
 7       border-radius: 50%;
 8       width: 25px;
 9       height: 25px;
10       text-align: center;
11       line-height: 25px;
12       color: #fff;
13     }
14     /* 插入或移除元素的过程 */
15     .list-enter-active, .list-leave-active {
16       transition: all 1s;
17     }
18     /* 开始插入或移除结束的位置变化 */
19     .list-enter, .list-leave-to {
20       opacity: 0;
21       transform: translateY(30px);
22     }
23   </style>
24   <script src="vue.js"></script>
25 </head>
26 <body>
27   <div id="app">
28     <button @click="add">随机插入一个数字</button>
29     <button @click="remove">随机移除一个数字</button>
30     <transition-group name="list" tag="p">
31       <span v-for="item in items" :key="item" class="list-item">
32         {{item}}
33       </span>
34     </transition-group>
35   </div>
36   <script>
37     var vm = new Vue({
38       el: '#app',
39       data: {
40         items: [1, 2, 3, 4, 5],     // 定义数字数组
41         nextNum: 6                        // 下一个数字从6开始
42       },
43       methods: {
44         randomIndex () {
45           return Math.floor(Math.random() * this.items.length)
46         },
47         add () {           // 单击“随机插入一个数字”时触发
48           this.items.splice(this.randomIndex(), 0, this.nextNum++)
49         },
50         remove () {         // 单击“随机移除一个数字”时触发
51           this.items.splice(this.randomIndex(), 1)
52         }
53       }
54     })
55   </script>

(3)效果展示:

2769248-20220425193130405-2098271753.gif

3.列表的排序过渡

为了实现列表平滑过渡,可以借助v-move特性。v-move 对于设置过渡的切换时机和过渡曲线非常有用。v-move特性会在元素改变定位的过程中应用,它同之前的类名一样,可以通过name属性来自定义前缀(例如name=“list”,则对应的类名就是list-move),当然也可以通过move-class属性手动设置自定义类名。

Vue使用了FLIP简单动画队列来实现排序过渡,所以即使没有插入或者移除元素,对于元素顺序的变化也支持过渡动画。FLIP动画能提高动画的流畅度,可以解决动画的卡顿、闪烁等不流畅的现象,它不仅可以实现单列过渡,也可以实现多维网格的过渡。FLIP代表First、Last、Invert、Play,有兴趣的读者可以自行研究学习。

(1)实现步骤:

  • 修改上述案例中的CSS部分,借助v-move和定位实现元素平滑过渡到新位置的效果。
  • 下载并引入lodash.min.js文件:首先从官方网站获取lodash.min.js文件,保存到文件目录中。其次创建html文件,并在文件中引入lodash.min.js文件
  • 编写HTML结构代码
  • 编写css样式代码
  • 编写js逻辑代码

(2)代码:

 1  <style>
 2     .list-item {
 3       display: inline-block;
 4       margin-right: 10px;
 5       background-color: red;
 6       border-radius: 50%;
 7       width: 25px;
 8       height: 25px;
 9       text-align: center;
10       line-height: 25px;
11       color: #fff;
12     }
13     /* 元素定位改变时动画 */
14     .list-move {
15       transition: transform 1s;
16     }
17   </style>
18   <script src="lodash.js"></script>
19   <script src="vue.js"></script>
20 </head>
21 <body>
22   <div id="app">
23     <button @click="shuffle">洗牌</button>
24     <transition-group name="list" tag="p">
25       <span v-for="item in items" :key="item" class="list-item">
26         {{ item }}
27       </span>
28     </transition-group>
29   </div>
30   <script>
31     var vm = new Vue({
32       el: '#app',
33       data () {
34         return { items: [1, 2, 3, 4, 5] }
35       },
36       methods: {
37         shuffle () {
38           // shuffle()函数把数组中的元素按随机顺序重新排列
39           this.items = _.shuffle(this.items)
40         }
41       }
42     })
43   </script>

(3)效果展示:

2769248-20220425193213830-843587380.gif

4.列表的交错过渡

在Vue中可以实现列表的交错过渡效果,它是通过data属性与JavaScript通信来实现的。接下来我们通过案例来讲解如何使用钩子函数结合Velocity.js库实现搜索功能,根据关键字来筛选出符合要求的列表数据,并添加过渡效果。

(1)实现步骤:

  • 下载并引入velocity.min.js文件:首先从官方网站获取velocity.min.js文件,保存到文件目录中。其次创建html文件,并在文件中引入velocity.min.js文件
  • 编写HTML结构代码
  • 编写js逻辑代码
  • 在浏览器预览效果
  • 搜索关键字“张”进行查找结果如下图所示

(2)代码:

 1 <div id="app">
 2     <input placeholder="请输入要查找的内容" v-model="query">
 3     <transition-group name="item" tag="ul" @before-enter="beforeEnter"
 4      @enter="enter" @leave="leave" v-bind:css="false">
 5       <li v-for="(item, index) in ComputedList" :key="item.msg"
 6        :data-index="index">
 7         {{ item.msg }}
 8       </li>
 9     </transition-group>
10   </div>
11   <script>
12     var vm = new Vue({
13       el: '#app',
14       data () {
15         return {
16           query: '',    // v-model绑定的值
17           items: [
18             { msg: '张三' },
19             { msg: '李四' },
20             { msg: '张芳芳' },
21             { msg: '王琳琳' },
22             { msg: '冯圆' }
23           ]
24         }
25       },
26       computed: {                     // 计算属性
27         ComputedList () {
28           var vm = this.query              // 获取到input输入框中的内容
29           var nameList = this.items      // 数组
30           return nameList.filter(function (item) {
31             return item.msg.toLowerCase().indexOf(vm.toLowerCase()) !== -1
32           })
33         }
34       },
35       methods: {
36         beforeEnter (el) {
37           el.style.opacity = 0
38           el.style.height = 0
39         },
40         enter (el, done) {
41           var delay = el.dataset.index * 150
42           setTimeout(function () {
43             Velocity(el, { opacity: 1, height: '1.6em' }, { complete: done })
44           }, delay)
45         },
46         leave (el, done) {
47           var delay = el.dataset.index * 150
48           setTimeout(function () {
49             Velocity(el, { opacity: 0, height: 0 }, { complete: done })
50           }, delay)
51         }
52       }
53     })
54   </script>

(3)效果展示:

2769248-20220425193242211-494999072.gif

5.可复用的过渡

在Vue中,过渡代码可以通过组件实现复用。若要创建一个可复用的过渡组件,需要将transition或者transition-group作为组件模板结构,然后在其内部通过插槽的方式编写列表结构即可。下面我们就来讲解两种实现过渡的封装的方式。

(1)实现步骤:

  • template方式,实现列表可复用的过渡
  • 浏览器预览效果如下图所示
  1. 函数式组件:是一种无状态(没有响应式数据)、无实例(没有this上下文)的组件。
  2. 函数式组件只是一个函数,渲染开销很低。

(2)代码:

 template方式

 1  <div id="app">
 2     <input placeholder="请输入要查找的内容" v-model="query">
 3     <fade :query="query" :items="items">
 4       <li v-for="(item, index) in ComputedList"
 5        :key="item.msg" :data-index="index">
 6         {{ item.msg }}
 7       </li>
 8     </fade>
 9   </div>
10 
11   <template id="temp">
12     <transition-group name="item" tag="ul" @before-enter="beforeEnter"
13      @enter="enter" @leave="leave" :css="false">
14       <slot></slot>
15     </transition-group>
16   </template>
17   
18   <script>
19     Vue.component('fade', {            // 定义组件名为fade
20       props: ['query', 'items'],    // 组件实例的属性
21       template: '#temp', 
22       methods: {
23         beforeEnter (el) {
24           el.style.opacity = 0
25           el.style.height = 0
26         },
27         enter (el, done) {
28           var delay = el.dataset.index * 150
29           setTimeout(function () {
30             Velocity(el, {opacity: 1, height: '1.6em'}, {complete: done})
31           }, delay)
32         },
33         leave (el, done) {
34           var delay = el.dataset.index * 150
35           setTimeout(function () {
36             Velocity(el, {opacity: 0, height: 0}, {complete: done})
37           }, delay)
38         }
39       }
40     })
41     var vm = new Vue({
42       el: '#app',
43       data: {
44         query: '',
45         items: [
46           { msg: '张三' },
47           { msg: '李四' },
48           { msg: '张芳芳' },
49           { msg: '王琳琳' },
50           { msg: '冯圆' }
51         ]
52       },
53       computed: {     // 计算属性
54         ComputedList () {
55           var vm = this.query
56           var nameList = this.items
57           return nameList.filter(function (item) {
58             return item.msg.toLowerCase().indexOf(vm.toLowerCase()) !== -1
59           })
60         }
61       }
62     })
63   </script>

函数式组件方式

 1 <div id="app">
 2     <input placeholder="请输入要查找的内容" v-model="query">
 3     <fade :query="query" :items="items">
 4       <li v-for="(item, index) in ComputedList" :key="item.msg"
 5        :data-index="index">
 6         {{ item.msg }}
 7       </li>
 8     </fade>
 9   </div>  
10   
11   <script>
12     Vue.component('fade', {
13       functional: true,      // 标记fade组件为函数式组件 
14       props: ['query', 'items'],
15       render (h, ctx) {
16         var data = {
17           props: {              // props组件
18             tag: 'ul',        // 修改默认渲染的span标签为ul
19             css: false
20           },
21           on: {
22             beforeEnter (el) {
23               el.style.opacity = 0
24               el.style.height = 0
25             },
26             enter (el, done) {
27               var delay = el.dataset.index * 150
28               setTimeout(function () {
29                 Velocity(el, { opacity: 1, height: '1.6em' }, { complete: done })
30               }, delay)
31             },
32             leave (el, done) {
33               var delay = el.dataset.index * 150
34               setTimeout(function () {
35                 Velocity(el, { opacity: 0, height: 0 }, { complete: done })
36               }, delay)
37             }
38           }
39         }
40         // data是传递给组件的数据对象,作为createElement()的第2个参数传入组件
41         // ctx.children是VNode子节点的数组
42         return h('transition-group', data,ctx.children)
43       }
44     })
45     var vm = new Vue({
46       el: '#app',
47       data: {
48         query: '',
49         items: [
50           { msg: '张三' },
51           { msg: '李四' },
52           { msg: '张芳芳' },
53           { msg: '王琳琳' },
54           { msg: '冯圆' }
55         ]
56       },
57       computed: {
58         ComputedList () {
59           var vm = this.query
60           var nameList = this.items 
61           return nameList.filter(function (item) {
62             return item.msg.toLowerCase().indexOf(vm.toLowerCase()) !== -1
63           })
64         }
65       }
66     })
67   </script>

注意:

在Vue 2.3.0版本及以下,如果一个函数式组件想要接收props,则必须有props选项;但是在2.3.0以上版本中,可以省略props选项,所有组件上的特性会被自动解析为props。

(3)效果展示:

2769248-20220425193259239-1343159007.gif

  1. 以上便是本篇文章所写的关于如何使用Vue的过渡和动画来实现想要的效果
  2. 内容包括transition组件的使用、内置的CSS类名、自定义类名、配合第三方CSS动画库animate.css实现过渡动画、在过渡钩子函数中使用JavaScript进行操作
  3. 以及配合第三方JavaScript动画库Velocity.js实现过渡动画。

通过以上的学习,各位笔友应该能够使用Vue完成一些简单的页面过渡效果和动画效果的展示。

码字不易,认为楼主写的还不错,对你有帮助的话,请给个三连(关注、点赞、收藏)另外有问题可评论区留言讨论

后期会完善Vue进阶语法的相关知识,有帮助的话,敬请关注楼主 持续更新中ing 。。。(不定时发文)

转载时请注明出处链接

百度云盘案列全套源码获取链接(地址如下):

 链接:https://pan.baidu.com/s/1_OhACAdsee2AiBOW7JrPbw?pwd=1234
提取码:1234

参考文档:

 1.vue官方文档:Vue.js (vuejs.org)

 2.传智播客-黑马程序员(教材):http://stu.ityxb.com/


其他随笔推荐:

1. 十大排序算法(Java实现)(作者力推):https://www.cnblogs.com/zbcxy506/p/zbcxy506_3arithmetic-01.html

2. Vue开发环境的部署:https://www.cnblogs.com/zbcxy506/p/zbcxy506_1vue-01.html

3. Vue基础入门一:https://www.cnblogs.com/zbcxy506/p/zbcxy506_1vue-02.html

4. Vue基础入门二:https://www.cnblogs.com/zbcxy506/p/note_1vue-03.html

5. Vue基础知识思维导图:https://www.cnblogs.com/zbcxy506/p/note_1vue-04.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK