feat: add merged venue navigation
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<view class="venue-tabbar-wrap">
|
||||
<view class="venue-tabbar-spacer" />
|
||||
<view class="venue-tabbar">
|
||||
<view
|
||||
v-for="item in items"
|
||||
:key="item.key"
|
||||
class="venue-tabbar__item"
|
||||
:class="{ active: item.key === active }"
|
||||
@tap="go(item)"
|
||||
>
|
||||
<image
|
||||
class="venue-tabbar__icon"
|
||||
:src="item.key === active ? item.activeIcon : item.icon"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="venue-tabbar__label">{{ item.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { setStoredVenue } from '@/utils/venue'
|
||||
|
||||
const props = defineProps({
|
||||
venue: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: (value) => ['ice', 'comprehensive'].includes(value)
|
||||
},
|
||||
active: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: (value) => ['home', 'courses', 'bookings', 'profile'].includes(value)
|
||||
}
|
||||
})
|
||||
|
||||
const tabDefinitions = [
|
||||
{ key: 'home', label: '首页', icon: 'home', path: 'home' },
|
||||
{ key: 'courses', label: '课程', icon: 'course', path: 'courses' },
|
||||
{ key: 'bookings', label: '预约', icon: 'booking', path: 'bookings' },
|
||||
{ key: 'profile', label: '我的', icon: 'mine', path: 'profile' }
|
||||
]
|
||||
|
||||
const items = computed(() => {
|
||||
return tabDefinitions.map((item) => ({
|
||||
...item,
|
||||
icon: `/static/${props.venue}/tab/${item.icon}.png`,
|
||||
activeIcon: `/static/${props.venue}/tab/${item.icon}-active.png`,
|
||||
url: `/pages/${props.venue}/${item.path}/index`
|
||||
}))
|
||||
})
|
||||
|
||||
const go = (item) => {
|
||||
setStoredVenue(props.venue)
|
||||
if (item.key === props.active) return
|
||||
|
||||
uni.reLaunch({ url: item.url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.venue-tabbar-spacer {
|
||||
height: calc(124rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.venue-tabbar {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
padding: 10rpx 0 calc(10rpx + env(safe-area-inset-bottom));
|
||||
border-top: 1rpx solid $border-color;
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.06);
|
||||
}
|
||||
|
||||
.venue-tabbar__item {
|
||||
min-width: 0;
|
||||
height: 104rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6rpx;
|
||||
color: $text-color-light;
|
||||
font-size: 22rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.venue-tabbar__item.active {
|
||||
color: $text-color-main;
|
||||
}
|
||||
|
||||
.venue-tabbar__icon {
|
||||
width: 46rpx;
|
||||
height: 46rpx;
|
||||
}
|
||||
|
||||
.venue-tabbar__label {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user