Vue Component Blog Post Example
by JRoger Song
HTML
<script src="https://unpkg.com/vue"></script>
<div id="dynamic-component-demo" class="demo">
<button
v-for="tab in tabs"
v-bind:key="tab"
v-bind:class="['tab-button', { active: currentTab === tab }]"
v-on:click="currentTab = tab"
>{{ tab }}</button>
<component
v-bind:is="currentTabComponent"
class="tab"
></component>
</div>
CSS
.tab-button {
padding: 6px 10px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border: 1px solid #ccc;
cursor: pointer;
background: #f0f0f0;
margin-bottom: -1px;
margin-right: -1px;
outline:none;
}
.tab-button:hover {
background: #e0e0e0;
}
.tab-button.active {
background: #666666;
color:white;
}
.tab {
border: 1px solid #ccc;
padding: 10px;
}
JavaScript
new Vue({
el: '#dynamic-component-demo',
data: {
currentTab: 'Home',
tabs: ['Home', 'Posts', 'Archive']
},
computed: {
currentTabComponent: function () {
let tabName = 'tab-' + this.currentTab.toLowerCase()
console.log(tabName);
if (tabName === 'tab-') return '';
this._registerTabComponent(tabName);
return tabName;
}
},
methods: {
_registerTabComponent(tabName) {
switch(tabName){
case 'tab-home':
Vue.component('tab-home', {
template: '<div>Home component</div>'
});
break;
case 'tab-posts':
Vue.component('tab-posts', {
template: '<div>Posts component</div>'
});
break;
case 'tab-archive':
Vue.component('tab-archive', {
template: '<div>Archive component</div>'
})
break;
}
}
}
})