一、实现效果
二、相关代码详情
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>动态组件</title>
<style>
div {
width: 250px;
}
.tab-button {
padding: 6px 10px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border: solid 1px #ccc;
cursor: pointer;
background: #f0f0f0;
margin-bottom: -1px;
margin-right: -1px;
}
.tab-button:hover {
background: #e0e0e0;
}
/* 当两个类之间无间隙时,只有都包含这两个类时才会显示出相关的效果 */
.tab-button.active {
background: #cdcdcd;
}
.tab {
border: solid 1px #ccc;
padding: 10px;
}
</style>
</head>
<body>
<div id="app">
<button v-for="tab in tabs" :key="tab.title" :class="['tab-button', {active: currentTab === tab.title}]" @click="currentTab = tab.title">{{tab.displayName}}</button>
<keep-alive>
<component v-bind:is = "currentTabComponent" class="tab"></component>
</keep-alive>
</div>
<script src="../../plugings/vue.js"></script>
<script>
Vue.component('tab-introduce', {
data() {
return {
content: '这是图书介绍'
}
},
template: '<div><input v-model="content"></div>'
})
Vue.component('tab-comment', {
template: '<div>这是图书评价</div>'
})
Vue.component('tab-qa', {
template: '<div>这是图书问答</div>'
})
new Vue({
el: '#app',
data: {
currentTab: 'introduce',
tabs: [
{title: 'introduce', displayName: '图书介绍'},
{title: 'comment', displayName: '图书评价'},
{title: 'qa', displayName: '图书问答'}
]
},
computed: {
currentTabComponent: function() {
return 'tab-' + this.currentTab;
}
}
})
</script>
</body>
</html>
三、关键代码分析
1、使用<keep-alive>元素将动态组件包裹起来,可以在组件进行切换中保持组件的状态,以避免渲染导致的性能问题。
2、组件的动态属性切换可以使用is属性进行切换,is属性的属性值是组件名称。
<keep-alive>
<component v-bind:is = "currentTabComponent" class="tab"></component>
</keep-alive>
3、通过计算属性来控制组件的切换,当点击不同的标签时data属性中的currentTab进行改变,此时currentTabComponent的值也会产生相关的改变,即is属性的属性值也会发生相应的改变。
computed: {
currentTabComponent: function() {
return 'tab-' + this.currentTab;
}
}