html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> <title>Title</title> </head> <body> <div id="app"> <tabs v-model="activeKey"> <pane label="图片"> 我是图片内容... </pane> <pane label="视频"> 我是视频内容... </pane> <pane label="音乐"> 我是音乐内容... </pane> <pane label="文章"> 我是文章内容... </pane> </tabs> </div> <script src="https://unpkg.com/vue/dist/vue.min.js"></script> <script src="pane.js"></script> <script src="tabs.js"></script> <script> var app = new Vue({ el: '#app', data: { activeKey: '0' } }) </script> </body> </html>
css:
[v-cloak] { display: none; } .tabs { font-size: 14px; color:#657180; } .tabs-bar:after{ content:''; display: block; width: 100%; height: 1px; background: #d7dde4; margin-top:-1px; } .tabs-tab { display: inline-block; padding: 4px 16px; margin-right: 6px; background: #ffffff; border: 1px solid #d7dde4; cursor: pointer; position: relative; } .tabs-tab-active { color: #3399ff; border-top: 1px solid #3399ff; border-bottom: 1px solid #ffffff; } .tabs-tab-active:before { content: ''; display: block; height: 1px; background: #3399ff; position: absolute; top: 0; left: 0; right: 0; } .tabs-content { padding: 8px 0; }
pane.js:
Vue.component('pane',{
name: 'pane',
template: '<div class="pane" v-show="show">
<slot></slot>
</div>',
props: {
label: {
type: String,
default: ''
}
},
data: function () {
return {
show: true
}
},
methods: {
updateNav: function () {
this.$parent.updateNav();
}
},
watch: {
label: function () {
this.updateNav();
}
},
mounted: function () {
this.updateNav();
}
})
tabs.js:
Vue.component('tabs',{
template: '<div class="tabs">
<div class="tabs-bar">
<div
v-for="(label,index) in navList"
:class="tabCls(index)"
@click="handleChange(index)">
{{label}}
</div>
</div>
<div class="tabs-content">
<slot></slot>
</div>
</div>',
props: {
value: {
type: String
}
},
data: function () {
return {
navList: [],
currentValue: this.value
}
},
methods: {
tabCls: function (index) {
return [
'tabs-tab',
{
'tabs-tab-active':index == this.currentValue
}
]
},
getTabs: function () {
return this.$children.filter(function (t) {
return t.$options.name === 'pane';
});
},
updateNav: function () {
this.navList = [];
var _this = this;
this.getTabs().forEach(function (t) {
_this.navList.push(t.label);
})
this.updateStatus();
},
updateStatus: function () {
var _this = this;
this.getTabs().forEach(function (t,i) {
t.show = i == _this.currentValue;
})
},
handleChange: function (index) {
this.currentValue = index;
this.$emit('input',index);
}
},
watch: {
currentValue: function () {
this.updateStatus();
},
value: function (val) {
this.currentValue = val;
}
}
})
效果图:
