动态组件适用于在不同组件之间进行动态切换。我使用过2种方法来实现:
(1)可以通过 Vue 的 <component>
元素加一个特殊的 is
特性来实现;
(2)通过v-if来进行条件渲染,同样能实现。
下面是2种实现方法的代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>动态组件的使用</title> 8 <style> 9 *{ 10 margin: 0; 11 padding: 0; 12 } 13 [v-cloak]{ /*防止刷新时闪烁 */ 14 display: none; 15 } 16 #app{ 17 margin:100px 200px; 18 } 19 button{ 20 width:80px; 21 height: 50px; 22 line-height: 50px; 23 font-size: 20px; 24 outline: none; 25 border-radius: 1px; 26 } 27 .isActive{ 28 background: #ccc; 29 } 30 .tab{ 31 width:600px; 32 height: 200px; 33 border:2px solid #ccc; 34 } 35 </style> 36 </head> 37 <body> 38 <div id="app" v-cloak> 39 <h3>方法1:使用v-if来实现组件之间动态切换</h3> 40 <button 41 v-for="tab in tabs" 42 :key="tab" 43 @click="setCurrentTab(tab)" 44 :class="{isActive:currentTab === tab}"> 45 {{ tab }} 46 </button> 47 <tab-home v-if="currentTab == 'Home'"></tab-home> 48 <tab-posts v-if="currentTab == 'Posts'"></tab-posts> 49 <tab-article v-if="currentTab == 'Article'"></tab-article> 50 51 <h3 style="margin-top: 50px;">方法二:使用<component is="currentTabComponent"></component>'来实现真正的动态组件切换</h3> 52 <button 53 v-for="tab in tabs" 54 :key="tab" 55 @click="setCurrentTab(tab)" 56 :class="{isActive:currentTab === tab}"> 57 {{ tab }} 58 </button> 59 <component :is="currentTabComponent"></component> 60 </div> 61 <script src="../vue.min.js"></script> 62 <script> 63 //定义3个组件----全局注册组件 64 Vue.component('tab-home',{ 65 template:` 66 <div class="tab"> 67 Home组件 68 </div> 69 ` 70 }) 71 Vue.component('tab-posts',{ 72 template:` 73 <div class="tab"> 74 Posts组件 75 </div> 76 ` 77 }) 78 Vue.component('tab-article',{ 79 template:` 80 <div class="tab"> 81 Article组件 82 </div> 83 ` 84 }) 85 var vm = new Vue({ 86 el:'#app', 87 data:{ 88 currentTab:'Home', 89 tabs:['Home','Posts','Article'] 90 }, 91 methods:{ 92 setCurrentTab:function(val){ //设置当前选中的选项卡 93 this.currentTab = val; 94 } 95 }, 96 computed:{ 97 currentTabComponent:function(){ 98 return 'tab-' + this.currentTab.toLowerCase(); //设置当前选中选项卡对应的组件 99 } 100 } 101 }) 102 </script> 103 </body> 104 </html>
结论:显然的是,使用Vue保留的元素<component :is="currentTabComponent"></component>更加方便高效。
值得注意的是:在这里注册的组件都是全局注册的,在<component :is="currentTabComponent"></component>中,currentTabComponent表示已全局注册的组件名称。但是currentTabComponent可以支持2种情况:
(1)即上述所说的已注册的组件名称
(2)一个组件的选项对象
第(2)种情况的使用,如下所示:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>动态组件</title> 8 <style> 9 *{ 10 margin: 0; 11 padding: 0; 12 } 13 [v-cloak]{ 14 display:none; 15 } 16 #app{ 17 margin: 100px 100px; 18 } 19 button{ 20 width: 120px; 21 height: 50px; 22 font-size: 20px; 23 line-height: 50px; 24 border-radius: 1px; 25 outline: none; 26 cursor: pointer; 27 } 28 .isActive{ 29 background: rgb(182, 179, 179); 30 } 31 .tab{ 32 width:600px; 33 height: 200px; 34 border:2px solid #ccc; 35 } 36 37 </style> 38 </head> 39 <body> 40 <div id="app" v-cloak> 41 <button 42 v-for="tab in tabs" 43 :key="tab.name" 44 @click="setCurrentTab(tab)" 45 :class="{isActive:currentTab.name === tab.name}"> 46 {{tab.name}} 47 </button> 48 <!-- 注意与使用组件名称的区别 --> 49 <component :is="currentTab.component" class="tab"></component> 50 </div> 51 <script src="../vue.min.js"></script> 52 <script> 53 //定义组件选项对象 54 var tabs = [ 55 { 56 name:"Home", 57 component:{ 58 template:`<div class="tab">Home组件</div>` 59 } 60 }, 61 { 62 name:"Posts", 63 component:{ 64 template:`<div class="tab">Posts组件</div>` 65 } 66 }, 67 { 68 name:"Article", 69 component:{ 70 template:`<div class="tab">Article组件</div>` 71 } 72 } 73 ]; 74 var vm = new Vue({ 75 el:'#app', 76 data:{ 77 tabs:tabs, 78 currentTab:tabs[0] 79 }, 80 methods:{ 81 setCurrentTab:function(val){ 82 this.currentTab = val; 83 } 84 } 85 }) 86 </script> 87 </body> 88 </html>