wz-uniapp/pages/military/components/military-tab-bar.vue

149 lines
3.1 KiB
Vue

<template>
<view class="tabbar-shell" :style="{ '--mask-color': maskColor }">
<view class="switch-mask" :class="{ show: isSwitching }"></view>
<view class="tabbar">
<view
v-for="tab in tabs"
:key="tab.key"
class="tab-item"
:class="{ active: active === tab.key }"
@click="onSwitch(tab)"
>
<view class="tab-active-bg"></view>
<uni-icons class="tab-icon" :type="tab.icon" :size="22" :color="active === tab.key ? tab.activeColor : '#98A0A6'" />
<text class="tab-label" :class="{ 'tab-label-active': active === tab.key }">{{ tab.label }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'MilitaryTabBar',
props: {
active: {
type: String,
default: 'home'
},
maskColor: {
type: String,
default: '#f4f6fb'
}
},
data() {
return {
isSwitching: false,
tabs: [
{ key: 'home', label: '首页', icon: 'home-filled', path: '/pages/military/home/home', activeColor: '#FF8A33' },
{ key: 'course', label: '课程', icon: 'staff-filled', path: '/pages/military/course/course', activeColor: '#FF8A33' },
{ key: 'plan', label: '军旅规划', icon: 'medal-filled', path: '/pages/military/plan/plan', activeColor: '#2B9C57' },
{ key: 'profile', label: '个人主页', icon: 'person-filled', path: '/pages/military/profile/profile', activeColor: '#FF8A33' }
]
};
},
methods: {
onSwitch(tab) {
if (tab.key === this.active || this.isSwitching) {
return;
}
this.isSwitching = true;
setTimeout(() => {
uni.switchTab({
url: tab.path,
complete: () => {
this.isSwitching = false;
}
});
}, 300);
}
}
};
</script>
<style scoped>
.tabbar-shell {
position: fixed;
left: 24rpx;
right: 24rpx;
bottom: 20rpx;
z-index: 9999;
}
.switch-mask {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 9998;
pointer-events: none;
opacity: 0;
background: var(--mask-color, #f4f6fb);
transition: opacity 0.3s ease;
}
.switch-mask.show {
opacity: 1;
}
.tabbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 18rpx 16rpx calc(18rpx + env(safe-area-inset-bottom));
border-radius: 32rpx;
background: #ffffff;
box-shadow: 0 10rpx 34rpx rgba(32, 43, 62, 0.14);
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
padding: 8rpx 0;
}
.tab-icon {
position: relative;
z-index: 2;
}
.tab-active-bg {
position: absolute;
left: 8rpx;
right: 8rpx;
top: 4rpx;
bottom: 4rpx;
border-radius: 20rpx;
background: linear-gradient(135deg, rgba(255, 173, 107, 0.36) 0%, rgba(68, 138, 255, 0.3) 100%);
opacity: 0;
transition: opacity 0.3s ease;
}
.tab-item.active .tab-active-bg {
opacity: 1;
}
.tab-label {
font-size: 22rpx;
line-height: 1.3;
margin-top: 8rpx;
position: relative;
z-index: 2;
color: #98A0A6;
transition: color 0.3s ease;
}
.tab-label-active {
background-image: linear-gradient(135deg, #ff8a33 0%, #2f86da 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-weight: 600;
}
</style>