Vue 组件封装之 TabBottom 底部导航
一、TabBottom 组件
组件说明:
实现底部 tab 切换。
效果展示:
底部 tab 切换,改变激活样式,切换到对应的页面
二、使用案例
说明:分别在【我的】、【添加】以及【团队】页面引用 el-tab-bottom 组件。
提示:可以将公共的 tabList 放在 store 中。
【我的】页面引用el-tab-bottom
<template>
<div>这是我的页面</div>
<el-tab-bottom :tabList="tabList" :defaultTab="0" @on-click="changeTabBottom"/>
</template>
<script>
export default{
data(){
return{
tabList:[
{title:'我的',path:'my',icon:my,checkedIcon:myCheck},
{title:'添加',path:'',icon:add,checkedIcon:addCheck},
{title:'团队',path:'myTeam',icon:myTeam,checkedIcon:myTeamChecked}
],
}
},
methods:{
changeTabBottom(item,index){},
}
}
</script>
【添加】页面引用el-tab-bottom
<template>
<div>这是添加页面</div>
<el-tab-bottom :tabList="tabList" :defaultTab="1" @on-click="changeTabBottom"/>
</template>
<script>
export default{
data(){
return{
tabList:[
{title:'我的',path:'my',icon:my,checkedIcon:myCheck},
{title:'添加',path:'',icon:add,checkedIcon:addCheck},
{title:'团队',path:'myTeam',icon:myTeam,checkedIcon:myTeamChecked}
],
}
},
methods:{
changeTabBottom(item,index){},
}
}
</script>
【团队】页面引用el-tab-bottom
<template>
<div>这是团队页面</div>
<el-tab-bottom :tabList="tabList" :defaultTab="2" @on-click="changeTabBottom"/>
</template>
<script>
export default{
data(){
return{
tabList:[
{title:'我的',path:'my',icon:my,checkedIcon:myCheck},
{title:'添加',path:'',icon:add,checkedIcon:addCheck},
{title:'团队',path:'myTeam',icon:myTeam,checkedIcon:myTeamChecked}
],
}
},
methods:{
changeTabBottom(item,index){},
}
}
</script>
三、API 使用指南
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
tabList | 数组,将底部的tab名称,路由等信息组合到tabList | Array | [] |
on-click | tab 被选中时触发 | 点击按钮的回调函数 | (e: Object): void |
defaultTab | 默认选中的tab | Number | 0 |
tabList 属性
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
title | 底部的tab文字 | string | “” |
path | 点击tab之后跳转到对应的页面路径名称 | string | “” |
icon | 未选中时的图标 | string | “” |
checkedIcon | 选中时的图标 | string | “” |
四、源代码
TabBottom.vue
<template>
<div class="tab-fill-height">
<div class="tab-position-fixed">
<div v-for="(item,index) in tabList"
@click="changeTab(item,index)"
:class="activeTab == index ? 'tab-title-active': 'tab-title'"
>
<img :src="activeTab == index ? item.checkedIcon:item.icon" alt="" class="tab-icon-20">
<div class="tab-text">{{item.title}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ElTabBottom",
data(){
return{
activeTab:0
}
},
created(){
this.activeTab = this.defaultTab;
},
//获取子组件传过来的激活tab
props:{
tabList:{
type: Array,
default: function () {
return [];
}
},
defaultTab:{
type:Number,
default:0
}
},
methods:{
changeTab(item,index){
//如果传了路由路径就是跳转页面,没传路径就交给父组件处理,比如 点击某个tab弹框而不是跳转页面。
if(item.path){
this.activeTab = index;//改变选中的底部tab样式
this.$router.push({name:item.path});//跳转对应的路由页面
};
this.$emit('on-click',item,index);//将点击Tab的事件暴露给父组件
}
}
}
</script>
<style>
//填充由fixed定位造成的数据流脱离高度
.tab-fill-height{
width: 100%;
height: 50px;
}
/*兼容iphoneXR底部遮住小黑条*/
@supports (bottom: env(safe-area-inset-bottom)){
.tab-position{
padding-bottom: calc(-50px + env(safe-area-inset-bottom));
}
}
//绝对定位
.tab-position-fixed{
position: fixed;
bottom: 0;
left: 0;
right:0;
height: 50px;
z-index: 999;
display: flex;
align-items: center;
justify-content: space-around;
background: #fff;
border-top: 1px solid #ddd;
}
//默认或者选中的tab样式
.tab-title-active{
color: #005398;
display: flex;
flex-direction: column;
align-items: center;
}
//未选中的tab样式
.tab-title{
color: #999;
display: flex;
flex-direction: column;
align-items: center;
}
//底部文字样式
.tab-text{
margin-top:3px;
font-size:12px
}
//底部图标大小
.tab-icon-20{
width: 20px;
height: 20px;
}
</style>