content
<template> <div class="tab-content"> <TabBar v-model="activeKey"> <TabBody label="标签一" name="1"> 标签一的内容 </TabBody> <TabBody label="标签二" name="2"> 标签二的内容 </TabBody> <TabBody label="标签三" name="3"> 标签三的内容 </TabBody> <TabBody label="标签四" name="4"> 标签四的内容 </TabBody> </TabBar> </div> </template> <script> import TabBar from '@/components/TabBar'; import TabBody from '@/components/TabBody'; export default { name:"tabContent", data() { return{ activeKey:'1' } }, components:{ TabBar, TabBody } } </script> <style lang="less"> .tab-header{ display: flex; justify-content: center; align-items: center; line-height: 30px; .tabs-item{ border-right: 1px solid #eee; padding: 0 10px; &:last-child{ border-right: 0; } } } .tab-content{ padding: 10px; } </style>
tabbar
<template> <div class="tab-bar"> <div class="tab-header"> <div class="tabs-item" :class="tabCls(item)" v-for="(item,idx) in navList" :key="idx" @click="handlerChange(idx)" > {{item.label}} </div> </div> <div class="tab-body"> <slot></slot> </div> </div> </template> <script> export default { props:{ value:{ type:[String,Number] } }, data(){ return{ currentValue:this.value, navList:[] } }, methods:{ tabCls(item){ return [ 'tabs-tab', { 'tabs-active':item.name == this.currentValue } ] }, handlerChange(idx){ let nav = this.navList[idx]; let name = nav.name; this.currentValue = name; this.$emit('input',name) this.$emit('on-click',name); }, getTabs(){ return this.$children.filter((item)=>{ return item.$options.name == 'pane' }) }, updateNav(){ this.navList = []; this.getTabs().forEach((pane,idx)=>{ this.navList.push({ label:pane.label, name:pane.name || idx }) if(!pane.name){ pane.nam = idx; } if(idx == 0){ if(!this.currentValue){ this.currentValue == pane.name || idx; } } }) this.updateStatus(); }, updateStatus(){ let tabs = this.getTabs(); tabs.forEach(item=>{ return item.show = item.name === this.currentValue; }) } }, watch:{ value(val){ this.currentValue = val; }, currentValue(){ this.updateStatus(); } } } </script> <style> </style>
tab-body
<template> <div class="tab-content" v-show="show"> <slot></slot> </div> </template> <script> export default { name:'pane', props:{ name:{ type:String }, label:{ type:String, default:'' } }, data() { return{ show:true } }, methods:{ updateNav(){ this.$parent.updateNav(); } }, mounted(){ this.updateNav(); }, watch:{ label(){ this.updateNav(); } } } </script> <style> </style>