动态组件适用于在不同组件之间进行动态切换。我使用过2种方法来实现:
(1)可以通过 Vue 的 <component> 元素加一个特殊的 is 特性来实现;
(2)通过v-if来进行条件渲染,同样能实现。
下面是2种实现方法的代码:
<!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">
<title>动态组件的使用</title>
<style>
*{
margin: 0;
padding: 0;
}
[v-cloak]{ /*防止刷新时闪烁 */
display: none;
}
#app{
margin:100px 200px;
}
button{
width:80px;
height: 50px;
line-height: 50px;
font-size: 20px;
outline: none;
border-radius: 1px;
}
.isActive{
background: #ccc;
}
.tab{
width:600px;
height: 200px;
border:2px solid #ccc;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<h3>方法1:使用v-if来实现组件之间动态切换</h3>
<button
v-for="tab in tabs"
:key="tab"
@click="setCurrentTab(tab)"
:class="{isActive:currentTab === tab}">
{{ tab }}
</button>
<tab-home v-if="currentTab == 'Home'"></tab-home>
<tab-posts v-if="currentTab == 'Posts'"></tab-posts>
<tab-article v-if="currentTab == 'Article'"></tab-article>
<h3 style="margin-top: 50px;">方法二:使用<component is="currentTabComponent"></component>'来实现真正的动态组件切换</h3>
<button
v-for="tab in tabs"
:key="tab"
@click="setCurrentTab(tab)"
:class="{isActive:currentTab === tab}">
{{ tab }}
</button>
<component :is="currentTabComponent"></component>
</div>
<script src="../vue.min.js"></script>
<script>
//定义3个组件----全局注册组件
Vue.component('tab-home',{
template:`
<div class="tab">
Home组件
</div>
`
})
Vue.component('tab-posts',{
template:`
<div class="tab">
Posts组件
</div>
`
})
Vue.component('tab-article',{
template:`
<div class="tab">
Article组件
</div>
`
})
var vm = new Vue({
el:'#app',
data:{
currentTab:'Home',
tabs:['Home','Posts','Article']
},
methods:{
setCurrentTab:function(val){ //设置当前选中的选项卡
this.currentTab = val;
}
},
computed:{
currentTabComponent:function(){
return 'tab-' + this.currentTab.toLowerCase(); //设置当前选中选项卡对应的组件
}
}
})
</script>
</body>
</html>
结论:显然的是,使用Vue保留的元素<component :is="currentTabComponent"></component>更加方便高效。
值得注意的是:在这里注册的组件都是全局注册的,在<component :is="currentTabComponent"></component>中,currentTabComponent表示已全局注册的组件名称。但是currentTabComponent可以支持2种情况:
(1)即上述所说的已注册的组件名称
(2)一个组件的选项对象
第2种情况的使用,如下所示:
<!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"> <title>动态组件</title> <style> *{ margin: 0; padding: 0; } [v-cloak]{ display:none; } #app{ margin: 100px 100px; } button{ width: 120px; height: 50px; font-size: 20px; line-height: 50px; border-radius: 1px; outline: none; cursor: pointer; } .isActive{ background: rgb(182, 179, 179); } .tab{ width:600px; height: 200px; border:2px solid #ccc; } </style> </head> <body> <div id="app" v-cloak> <button v-for="tab in tabs" :key="tab.name" @click="setCurrentTab(tab)" :class="{isActive:currentTab.name === tab.name}"> {{tab.name}} </button> <!-- 注意与使用组件名称的区别 --> <component :is="currentTab.component" class="tab"></component> </div> <script src="../vue.min.js"></script> <script> //定义组件选项对象 var tabs = [ { name:"Home", component:{ template:`<div class="tab">Home组件</div>` } }, { name:"Posts", component:{ template:`<div class="tab">Posts组件</div>` } }, { name:"Article", component:{ template:`<div class="tab">Article组件</div>` } } ]; var vm = new Vue({ el:'#app', data:{ tabs:tabs, currentTab:tabs[0] }, methods:{ setCurrentTab:function(val){ this.currentTab = val; } } }) </script> </body> </html>
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!