ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >[success] # 组件和元素切换动画的实现 1. **多元素的切换动画** 之前上一章讲过**单元素动画** ,这次讲一下 **多元素的动画** ,实际上单元素与 **多元素** 写法都一样,代码如下: **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件和元素切换动画的实现</title> <style> /* -------------------入场动画----------------------- */ .v-enter-from{ opacity: 0; } .v-enter-active{ transition: opacity 3s ease-in; } .v-enter-to { opacity: 1; } /* -------------------出场动画----------------------- */ .v-leave-from{ opacity: 1; } .v-leave-active{ transition: opacity 3s ease-in; } .v-leave-to { opacity: 0; } </style> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> const app = Vue.createApp({ data(){ return { show: false } }, methods: { handleClick(){ this.show = !this.show } }, template: ` <div> <transition> <div v-if="show">hello world</div> <div v-else="show">bye world</div> </transition> <button @click="handleClick">切换</button> </div>` }) const vm = app.mount('#root') </script> </html> ~~~ 上面虽然实现了 **多元素动画** 的效果,但是有一个问题:**hello world 展示时候,bye world 慢慢悠悠的消失,导致每次切换时候能同时看到2个元素,如果想每次一个元素隐藏结束了,再显示另外一个元素** ,如何解决呢,只需要在 **transition标签** 上添加 **mode="out-in"** 就行,意思就是 **先隐藏后展示,先出去再进来(in-out 先进再出 out-in 先出再进)** , 代码如下: ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件和元素切换动画的实现</title> <style> /* -------------------入场动画----------------------- */ .v-enter-from{ opacity: 0; } .v-enter-active{ transition: opacity 3s ease-in; } .v-enter-to { opacity: 1; } /* -------------------出场动画----------------------- */ .v-leave-from{ opacity: 1; } .v-leave-active{ transition: opacity 3s ease-in; } .v-leave-to { opacity: 0; } </style> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> const app = Vue.createApp({ data(){ return { show: false } }, methods: { handleClick(){ this.show = !this.show } }, template: ` <div> <transition mode="out-in"> <div v-if="show">hello world</div> <div v-else="show">bye world</div> </transition> <button @click="handleClick">切换</button> </div>` }) const vm = app.mount('#root') </script> </html> ~~~ 刚进入页面时候 **bye world** 是没有动画的,如果希望刚进入页面 **bye world** 就有一个动画效果,可以给 **transition标签** 添加一个 **appear** 属性,它的意思是 **初次对某一个默认元素显示的时候会给它带上我们写的这个动画效果** ,代码如下: ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件和元素切换动画的实现</title> <style> /* -------------------入场动画----------------------- */ .v-enter-from{ opacity: 0; } .v-enter-active{ transition: opacity 3s ease-in; } .v-enter-to { opacity: 1; } /* -------------------出场动画----------------------- */ .v-leave-from{ opacity: 1; } .v-leave-active{ transition: opacity 3s ease-in; } .v-leave-to { opacity: 0; } </style> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> const app = Vue.createApp({ data(){ return { show: false } }, methods: { handleClick(){ this.show = !this.show } }, template: ` <div> <transition mode="out-in" appear> <div v-if="show">hello world</div> <div v-else="show">bye world</div> </transition> <button @click="handleClick">切换</button> </div>` }) const vm = app.mount('#root') </script> </html> ~~~ 2. **多组件的切换动画** **多组件** 的切换没什么不同只是改成了 **组件** 的形式,代码如下: **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件和元素切换动画的实现</title> <style> /* -------------------入场动画----------------------- */ .v-enter-from{ opacity: 0; } .v-enter-active{ transition: opacity 1s ease-in; } .v-enter-to { opacity: 1; } /* -------------------出场动画----------------------- */ .v-leave-from{ opacity: 1; } .v-leave-active{ transition: opacity 1s ease-in; } .v-leave-to { opacity: 0; } </style> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 多个单元素标签之间的切换 // 多个单组件之间的切换 const ComponentA = { template: '<div>hello world</div>' } const ComponentB = { template: '<div>bye world</div>' } const app = Vue.createApp({ data(){ return { show: false } }, components: { 'component-a': ComponentA, 'component-b': ComponentB }, methods: { handleClick(){ this.show = !this.show } }, template: ` <div> <transition mode="out-in" appear> <component-a v-if="show" /> <component-b v-else="show" /> </transition> <button @click="handleClick">切换</button> </div>` }) const vm = app.mount('#root') </script> </html> ~~~ 或者也可以写成 **动态组件** ,代码如下: ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件和元素切换动画的实现</title> <style> /* -------------------入场动画----------------------- */ .v-enter-from{ opacity: 0; } .v-enter-active{ transition: opacity 1s ease-in; } .v-enter-to { opacity: 1; } /* -------------------出场动画----------------------- */ .v-leave-from{ opacity: 1; } .v-leave-active{ transition: opacity 1s ease-in; } .v-leave-to { opacity: 0; } </style> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 多个单元素标签之间的切换 // 多个单组件之间的切换 const ComponentA = { template: '<div>hello world</div>' } const ComponentB = { template: '<div>bye world</div>' } const app = Vue.createApp({ data(){ return { component: 'component-a' } }, components: { 'component-a': ComponentA, 'component-b': ComponentB }, methods: { handleClick(){ if(this.component === 'component-a'){ this.component = 'component-b' } else { this.component = 'component-a' } } }, template: ` <div> <transition mode="out-in" appear> <component :is="component" /> </transition> <button @click="handleClick">切换</button> </div>` }) const vm = app.mount('#root') </script> </html> ~~~