tab标签控件为例
step1:总控件
tabs.vue
<script>
import TabContainer from './tab-container.vue'
export default {
name: 'Tabs',
components: {
TabContainer
},
/*provide() {
return {
value: this.value //非reactive, 可用define方法解决
}
},*/
props: {
value: {
type: [String, Number],
required: true
}
},
data() {
return {
panes: []
}
},
render() {
return (
<div class="tabs">
<ul class="tabs-header"> //tab插入插槽中
{this.$slots.default }
</ul>
<tab-container panes={this.panes}></tab-container> //下container展示内容
</div>
)
},
methods: {
onChange(index) {
this.$emit('change', index)
}
},
}
</script>
<style lang="stylus" scoped>
.tabs-header
display flex
list-style none
margin 0
padding 0
border-bottom 2px solid #ededed
</style>
step2:上部控件
tab.vue
<script>
export default {
name: 'Tab',
props: {
index: {
required: true,
type: [Number, String]
},
label: {
type: String,
default: 'tab'
}
},
//inject: ['value'],
mounted() {
this.$parent.panes.push(this)
},
computed: {
active() {
//console.log("active is invoked ===",index)
return this.$parent.value === this.index
//return this.value === this.index //组件套用的时候用provider
}
},
methods: {
handleClick() {
this.$parent.onChange(this.index)//d调用上层方法
}
},
render() {
const tab = this.$slots.label || <span>{this.label}</span>
const classNames = {
tab: true,
active: this.active
}
return (
<li class ={classNames} on-click={this.handleClick}>
{tab}
</li>
)
}
}
</script>
<style lang="stylus" scoped>
.tab
list-style none
line-height 40px
margin-right 30px
position relative
bottom -2px
cursor pointer
&.active
border-bottom 2px solid black
&:last-child
margin-right 0
</style>
step3:内容控件
tab-container.vue
<script>
export default {
props: {
panes: {
type: Array,
required: true
}
},
render() {
const contents = this.panes.map(pane => {
return pane.active ? pane.$slots.default : null
})
return (
<div class="tab-content">
{contents}
</div>
)
}
}
</script>
step4:挂载到全局Vue上
index.js
import Tabs from './tabs.vue'
import Tab from './tab.vue'
export default (Vue) => {
Vue.component(Tabs.name, Tabs)
Vue.component(Tab.name, Tab)
}
————--------------——show time again,baby!!!———---------------—————
todu.vue
<template>
<section class="real-app">
<div class="tab-container">
<tabs :value="filter" @change="handleChangeTab"> //直接引用,定制显示数据
<tab :label="tab" :index="tab" v-for="tab in stats" :key="tab"/>
</tabs>
</div>
......
data() {
return {
stats: ['all', 'active', 'completed'],
filter: 'all',
todos: [],
}
},采坑记录: