Vue中的动画效果
作者:@skyflask
转载本文请注明出处:https://www.cnblogs.com/skyflask/p/10990482.html
目录
一、单元素/组件的过渡
二、Vue使用animate.css动画库
三、Vue中同时使用过渡和动画
四、Vue中的js动画配合使用第三方动画库(Velocity.js)
五、多个元素或组件的过渡动画
六、Vue中列表的过渡动画
七、动画封装
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
包括以下工具:
- 在 CSS 过渡和动画中自动应用 class
- 可以配合使用第三方 CSS 动画库,如 Animate.css
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
下面分别从这个4个工具来学习Vue动画效果。
一、单元素/组件的过渡
Vue 提供了 transition
的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
- 条件渲染 (使用
v-if
) - 条件展示 (使用
v-show
) - 动态组件
- 组件根节点
一个典型的例子:
Html文件
1 2 3 4 5 6 7 8 | <div id= "app" > <transition name= "fade" > <div v- if = "show" > Hello world. </div> </transition> <button @click= "handleClick" >切换</button> </div> |
js文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <script> // 1. 创建Vue的实例 let vm = new Vue({ el: '#app' , data:{ show: false }, methods:{ handleClick:function(){ this .show = ! this .show } } }); </script> |
css文件
1 2 3 4 5 6 7 8 | <style> .fade-enter-active, .fade-leave-active { transition: opacity 2s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style> |
这个例子的效果为:点击切换,文字会淡入淡出。
实现原理:
1、通过使用transition组件后, Vue 将会做以下处理:
- 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
- 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
- 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的
nextTick
概念不同)
2、动画进入时,Vue会添加CSS类,如果没有使用name="fade"的话,类名为v-fade-enter、v-fade-eneter-active等。
第一帧动画,会自动添加fade-enter和fade-enter-active类
第二帧动画,会去掉fade-enter类,添加fade-enter-to类
第三帧动画,会去掉所有enter类
3、动画在离开时同样会添加或删除CSS类
二、Vue使用animate.css动画库
1、使用自定义类
效果为:进入或离开都会有拉升效果。
注意:这里我们使用了
1 | name= "bounce" 替换了默认的fade。当然,如果没有fade的话,也会有v-作为默认开头。 |
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 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <title></title> <style> @keyframes bounce- in { 0% { transform: scale(0); } 50% { transform: scale(1.5); } 100% { transform: scale(1); } } .bounce-enter-active { animation: bounce- in .5s; } .bounce-leave-active { animation: bounce- in .5s reverse; } </style> </head> <body> <div id= "app" > <transition name= "bounce" > <div v- if = "show" > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus. </div> </transition> <button @click= "handleClick" >切换</button> </div> <script src= "js/vue.js" ></script> <script> // 1. 创建Vue的实例 let vm = new Vue({ el: '#app' , data:{ show: false }, methods:{ handleClick:function(){ this .show = ! this .show } } }); </script> </body> </html> |
我们这里还可以使用自定义类:
既然我们可以使用自定义class,那么我们就可以使用开源的第三方CSS库,比如animate.css库。
https://daneden.github.io/animate.css/
使用很简单,直接替换上面我们自定义的class就行。
使用animate.css注意事项:
1、必须使用自定义class的模式
enter-active-class=""
2、animated类放在前面,且是必须的
三、Vue中同时使用过渡和动画
1、初次动画效果
上面例子中,我们初次进入的时候没有动画效果,我们可以做如下修改:
2、如果我们希望在上面的例子中还加入一开始我们说的过渡效果,那该怎么做呢?
1、因为animate.css有一个自己的动画效果时长,fade也有一个opacity,那么以哪一个为准呢?我们可以使用type="transition"来确定哪个为准。
2、我们也可以自己设定动画效果时长样式:duration里面的enter为进入时长,leave为动画离开时长,都是针对过渡效果的。
四、Vue中的js动画配合使用第三方动画库(Velocity.js)
Html
1 2 3 4 5 6 7 8 9 10 11 | <div id= "app" > <transition name= "fade" @before-enter= "beforeEnter" @enter= "enter" > <div v- if = "show" > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus. </div> </transition> <button @click= "handleClick" >切换</button> </div> |
Js
1 2 3 4 5 6 7 8 9 10 11 12 13 | methods:{ handleClick:function(){ this .show = ! this .show }, beforeEnter: function (el) { el.style.opacity = 0 el.style.transformOrigin = 'left' }, enter: function (el, done) { Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 }) Velocity(el, { fontSize: '1em' }, { complete: done }) }, } |
五、多个元素或组件的过渡动画
1、多个元素的过渡动画实现
Html
1 2 3 4 5 6 7 | <div id= "app" > <transition name= "fade" mode= "in-out" > <div v- if = "show" key= 'one' >组件1</div> <div v- else key= 'two' >组件2</div> </transition> <button @click= "handleClick" >切换</button> </div> |
style
1 2 3 4 5 6 7 8 | <style> .fade-enter-active, .fade-leave-active { transition: opacity 1s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style> |
注意:这里需要绑定一个key,因为vue会复用,所以不加key就不会有效果。
2、多个组件的过渡动画实现
Html
1 2 3 4 5 6 7 | <div id= "app" > <transition name= "fade" > <child-one v- if = "show" ></child-one> <child-two v- else ></child-two> </transition> <button @click= "handleClick" >切换</button> </div> |
js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <script> Vue.component( 'child-one' ,{ template: '<div>child-one</div>' }) Vue.component( 'child-two' ,{ template: '<div>child-two</div>' }) // 1. 创建Vue的实例 let vm = new Vue({ el: '#app' , data:{ show: false }, methods:{ handleClick:function(){ this .show = ! this .show } } }); </script> |
css
1 2 3 4 5 6 7 8 | <style> .fade-enter-active, .fade-leave-active { transition: opacity .4s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style> |
我们可以通过Vue自带的compoent标签实现动态组件,data中show改成type,type:‘child-one’
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 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <title></title> <style> .fade-enter-active, .fade-leave-active { transition: opacity .4s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style> </head> <body> <div id= "app" > <transition name= "fade" > <component : is = "type" ></component> </transition> <button @click= "handleClick" >切换</button> </div> <script src= "js/vue.js" ></script> <script> Vue.component( 'child-one' ,{ template: '<div>child-one</div>' }) Vue.component( 'child-two' ,{ template: '<div>child-two</div>' }) // 1. 创建Vue的实例 let vm = new Vue({ el: '#app' , data:{ type: 'child-one' }, methods:{ handleClick:function(){ this .type = this .type=== 'child-one' ? 'child-two' : 'child-one' } } }); </script> </body> </html> |
六、Vue中列表的过渡动画
当我们希望对列表进行过渡效果时,使用transition-group标签就可以了。
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 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <title></title> <style> .fade-enter-active, .fade-leave-active { transition: opacity 1s; color: red; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style> </head> <body> <div id= "app" > <transition- group name= "fade" > <div v- for = "item in list" key= "item.id" >{{item.title}}</div> </transition- group > <button @click= "handleClick" >增加</button> </div> <script src= "js/vue.js" ></script> <script> var count = 0 // 1. 创建Vue的实例 let vm = new Vue({ el: '#app' , data:{ list:[] }, methods:{ handleClick:function(){ this .list.push({ id:count++, title: 'hello kitty!' }) } } }); </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 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <title></title> <script src= 'js/velocity.min.js' ></script> </head> <body> <div id= "app" > <fade :show= "show" > <div> hello div </div> </fade> <fade :show= "show" > <h1>hello H1</h1> </fade> <button @click= "handleClick" >增加</button> </div> <script src= "js/vue.js" ></script> <script> Vue.component( 'fade' ,{ props:[ 'show' ], template:`<transition @before-enter= "handleBeforeEnter" @enter= "handleEnter" > <slot v- if = "show" ></slot> </transition>`, methods:{ handleBeforeEnter:function(el){ el.style.color= "red" }, handleEnter:function(el,done){ setTimeout(()=>{ Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 }) Velocity(el, { fontSize: '1em' }, { complete: done }) done() },2000) } } }) // 1. 创建Vue的实例 let vm = new Vue({ el: '#app' , data:{ show: false }, methods:{ handleClick:function(){ this .show=! this .show } } }); </script> </body> </html> |
我们这里封装了一个fade组件,通过transition封装一个slot,里面可以支持N个内容。然后将动画效果封装到钩子函数,然后在钩子函数里面放入CSS效果。这样,就将动画效果完全封装在一个组件中了,随时随地可以使用这个带动画的组件啦。
写了这么多,其实就是开头的四种方式:
- 在CSS过渡和动画中自动应用class【默认为fade开头,也可以自定义,不写name时为v开头】
- 可以配合使用第三方 CSS 动画库,如 Animate.css【自定义class的方式】
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!