页面使用时
<Tabs :currentIndex="currentIndex" @onIndexChange="getIndex">
<Tab index="1" tabName="标题1">
<div>内容1</div>
</Tab>
<Tab index="2" tabName="标题2">
<div>内容2</div>
</Tab>
<Tab index="3" tabName="标题3">
<div>内容3</div>
</Tab>
</Tabs>
<script>
export default {
name: 'App',
data(){
return{
currentIndex:0
}
},
methods:{
getIndex(index){
this.currentIndex = index
}
}
}
</script>
定义为全局组件index.js
import Tabs from "./tabs"
import Tab from "./tab"
export default (Vue) => {
Vue.component(Tabs.name,Tabs)
Vue.component(Tab.name,Tab)
}
在主入口文件main.js中引入
import Tabs from './components/Tabs/index'
Vue.use(Tabs)
tabs.vue
<script>
import Content from "./content";
export default {
name: "Tabs",
data() {
return {
contents:[]
};
},
components: {
Content
},
props: {
currentIndex: {
type: [String, Number],
default: "0"
}
},
methods: {
onChangeIndex(index) {
this.$emit("onIndexChange", index);
}
},
render() {
return (
<div>
<ul class="tabs-header">{this.$slots.default}</ul>
<Content contents={ this.contents }/>
</div>
);
}
};
</script>
tab.vue
<script>
export default {
name: "Tab",
data() {
return {};
},
props: {
index: {
type: [String, Number],
default: "1"
},
tabName:{
type:String,
default:"tab"
}
},
mounted() {
// this:当前组件
this.$parent.contents.push(this);
},
computed: {
active() {
return this.$parent.currentIndex == this.index;
}
},
methods:{
clickTabHandler(){
this.$parent.onChangeIndex(this.index);
}
},
render() {
let className = {
tab: true,
active: this.active
};
return <li class={className} onClick={this.clickTabHandler}>{ this.tabName }</li>;
}
};
</script>
content.vue
<script>
export default {
name:"Content",
data(){
return{
}
},
props:{
contents:{
type:Array
}
},
render(){
return(
<div>
{
this.contents.map((element,index) => {
return (
<div>
{ element.active ? element.$slots.default : '' }
</div>
)
})
}
</div>
)
}
}
</script>
1. 使用页面中homeTab.vux:
Tabs
-
动态绑定:currentIndex='currentIndex'
-
点击事件发生时,重新设置currentIndex
<Tabs :currentIndex="currentIndex" @onchangeIndex="getIndex">
data() {
return {
currentIndex: 0,
tabData: []
};
},
methods: {
getIndex(index) {
this.currentIndex = index;
}
}
Tab
通过网络请求获取数据tabData,循环遍历生成Tab,绑定index,tabName传送给Tab.vux
import axios from "axios";
mounted() {
const _this = this;
function newsList() {
return _this.$api.getMusicList({
method: "baidu.ting.billboard.billList",
type: 1,
size: 5,
offset: 0
});
}
function oldList() {
return _this.$api.getMusicList({
method: "baidu.ting.billboard.billList",
type: 2,
size: 5,
offset: 0
});
}
function classicList() {
return _this.$api.getMusicList({
method: "baidu.ting.billboard.billList",
type: 22,
size: 5,
offset: 0
});
}
axios.all([newsList(), oldList(), classicList()]).then(
axios.spread((newsListData, oldListData, classicListData) => {
_this.tabData.push(
newsListData.data,
oldListData.data,
classicListData.data
);
})
);
}
例子:
<template>
<div class="tabs">
<Tabs :currentIndex="currentIndex" @onchangeIndex="getIndex">
<Tab
v-for="(element,index) in tabData"
:key="index"
:index="index"
:tabName="element.billboard.name"
>
<div class="panel hotsongs on">
<ul class="list">
<li class="song url" v-for="(item,index) in element.song_list" :key="index">
<div class="poster">
<img :src="item.pic_big" :alt="item.title" />
</div>
<div class="info">
<div class="name">{{ item.title }}</div>
<div class="author">{{ item.artist_name }}</div>
</div>
</li>
</ul>
<div class="more-songs url">查看该榜单></div>
</div>
</Tab>
</Tabs>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "HomeTab",
data() {
return {
currentIndex: 0,
tabData: []
};
},
methods: {
getIndex(index) {
this.currentIndex = index;
}
},
mounted() {
const _this = this;
function newsList() {
return _this.$api.getMusicList({
method: "baidu.ting.billboard.billList",
type: 1,
size: 5,
offset: 0
});
}
function oldList() {
return _this.$api.getMusicList({
method: "baidu.ting.billboard.billList",
type: 2,
size: 5,
offset: 0
});
}
function classicList() {
return _this.$api.getMusicList({
method: "baidu.ting.billboard.billList",
type: 22,
size: 5,
offset: 0
});
}
axios.all([newsList(), oldList(), classicList()]).then(
axios.spread((newsListData, oldListData, classicListData) => {
console.log(newsListData, oldListData, classicListData);
_this.tabData.push(
newsListData.data,
oldListData.data,
classicListData.data
);
})
);
}
};
2. Tabs.vux中引入Content组件,并传递数据contents,通过自定义事件将当前点击的index传入使用页面
例子:
<script>
import Content from './content'
export default {
name:'Tabs',
data(){
return{
contents:[]
}
},
components:{Content},
render(){
return(
<div>
<ul class="tabs-header">{this.$slots.default}</ul>
<Content contents={this.contents}/>
</div>
)
},
props:{
currentIndex:{
type:[String,Number]
}
},
methods:{
changeIndex(index){
this.$emit('onchangeIndex',index)
}
},
}
</script>
3. Tab.vux
接收index,tabName;
调用父组件中的事件,将当前index传递过去;
调用父组件的currentIndex,设置当前选中的li的样式;
将当前组件保存在conten中,供content渲染页面;
例子:
<script>
export default {
name: "Tab",
props: {
tabName: {
type: String,
default: 'tab'
},
index: {
type: [Number, String],
default: 0
}
},
mounted() {
this.$parent.contents.push(this);
},
computed: {
active() {
return this.$parent.currentIndex == this.index;
}
},
methods: {
clickEvent() {
this.$parent.changeIndex(this.index);
}
},
render() {
let className = {
tab: true,
active: this.active
};
return (
<li class={className} onClick={this.clickEvent}>
{this.tabName}
</li>
);
}
};
</script>
<style>
.tab {
flex: 1;
list-style: none;
line-height: 40px;
margin-right: 30px;
position: relative;
text-align: center;
}
.tab.active {
border-bottom: 2px solid blue;
}
</style>
4. content.vue
通过class的true/false决定当前显示内容
<script>
export default {
name:'Content',
props:{
contents:{
type:Array
}
},
render(){
return(
<div>
{
this.contents.map((ele,index)=>{
return (
<div>
{
ele.active?ele.$slots.default:''
}
</div>
)
})
}
</div>
)
}
}
</script>