A tab page build, including three files, why this.$emit ("input",name) in tabs.js?
<!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">
<style type="text/css" href="style.css"></style>
<title>vue</title>
</head>
<body>
<div id="app">
<tabs v-model="activeKey">
<pane label="1" name="1" >
1
</pane>
<pane label="2" name="2" >
2
</pane>
<pane label="3" name="3" >
3
</pane>
</tabs>
</div>
<script src="../vue.js"></script>
<script type="text/javascript" src="pane.js"></script>
<script type="text/javascript" src="tab.js"></script>
<script>
var app=new Vue({
el:"-sharpapp",
data(){
return {
activeKey:1
}
}
})
</script>
</body>
</html>
pane.js file
//label
Vue.component("pane",{
template:
`
<div class="pane" v-show="show">
<slot></slot>
</div>
`,
props:{
label:{
type:String,
default:""
},
name:{
type:String
}
},
data(){
return {
show:true
}
},
methods:{
updateNav(){
this.$parent.updateNav();
}
},
watch:{
label(){
this.updateNav();
}
},
mounted(){
this.updateNav();
}
});
tabs.js
Vue.component("tabs",{
template:`
<div class="tabs">
<div class="tabs-bar">
<div :class="tabCls(item)"
v-for="(item,index) in navList"
@click="handleChange(index)">
{{item.label}}
</div>
</div>
<div class="tab-content">
<slot></slot>
</div>
</div>
`,
props:{
//v-model
value:{
type:[String,Number]
}
},
data(){
return {
//tabs
navList:[],
currentValue:this.value
}
},
methods:{
tabCls(item){
return ["tabs-tab",
{
"tabs-tab-active" : item.name===this.currentValue
}
]
},
//
handleChange(index){
var nav=this.navList[index];
var name=nav.name;
//tabwatch
this.currentValue=name;
//value?
this.$emit("input",name);
},
getTabs(){
//pane
console.log(this)
console.log(this.$children);
return this.$children.filter(item=>item.$options.name==="pane")
},
updateNav(){
this.navList=[];
this.getTabs().forEach((pane,index)=>{
this.navList.push({
label:pane.label,
name:pane.name || index
});
//panelname
if(!pane.name){
pane.name=index;
}
//
if(index===0){
if(!this.currentValue){
this.currentValue=pane.name || index;
}
}
});
this.updateStatus();
},
updateStatus(){
var tabs=this.getTabs();
tabs.forEach(tab=>{
return tab.show=tab.name===this.currentValue;
})
}
},
watch:{
value(val){
this.currentValue=val;
},
currentValue(){
//tabpanel
this.updateStatus();
}
}
})