<script setup> /** 底部菜单导航 * 底部导航的规则 * 视频端显示: * 视频 商城 消息 我的(视频我的) * 商城端显示: * 视频 商城 消息 个人中心(商城我的) */ import { ref, computed, onMounted, onUnmounted, getCurrentInstance, reactive, } from 'vue' // 工具库 import util from '@/common/js/util'; const { proxy } = getCurrentInstance() // 接收参数 const props = defineProps({ page: { type: String, }, // 主题 dark黑色 light白色的 subject: { type: String, default: 'light', }, }) // 用户信息 const userinfo = computed(() => { let resuilt = uni.$store.state.userinfo return resuilt }) // 展示模式 商城shop 默认default const mode = computed(() => uni.$store.state.tabbarMode) // 底部菜单 const menu = computed(() => { let arr = [{ page: 'index', type: 'option', name: '视频', pagePath: 'pages/index/index', }, // { // page: '', // type: 'option', // name: '榴莲果', // pagePath: 'pages/index/durian', // }, { page: 'shop', type: 'option', name: '商城', pagePath: 'pages/shop/shop' }, { type: 'middle', name: '', }, { page: 'news', type: 'option', name: '消息', pagePath: 'pages/news/news', } ] switch (mode.value) { case 'default': // 发布视频 arr[2].pagePath = 'pages/release/video' arr.push({ page: 'mine', type: 'option', name: '我的', pagePath: 'pages/mine/homepage', }) break; case 'shop': arr[2].pagePath = 'pages/merchant/commodity-release/index' arr.push({ page: 'mine', type: 'option', name: '个人中心', pagePath: 'pages/mine/mine', }) break; } return arr }) // 安全区高度 let safeHeight = ref(0) // 弹窗菜单 const showMenu = computed(() => { let result = [] // 验证登录 if (userinfo.value.userId) { result.push({ name: '发布视频', img: '/static/footerMenu1.png', url: '/pages/release/video', }) } // 追加 // result.push({ // name: '打车', // }, { // name: '充电', // }, { // name: '到店美食', // }, { // name: '出行', // }, { // name: '家政', // }) return result }) // 加载完成之后 onMounted(() => { // 开启监听 addListener() // 隐藏tabbar uni.hideTabBar() // 系统信息 uni.getSystemInfo().then(rs => { safeHeight.value = rs.safeArea + 'px' }) // // proxy.$refs.alert.open() }) // 卸载 onUnmounted(() => { uni.$off('changeMine') }) // 开启监听 function addListener() { // 修改个人中心的状态 uni.$on('changeMine', (value) => { uni.$store.commit('setState', { key: 'tabbarMode', value, }) }) } /** * 点击菜单 * @param {Object} item 当前点击的菜单项 */ function handleMenu(item) { if (item.type != 'middle') { // 判断是否配置页 if (item.page) uni.switchTab({ url: `/${item.pagePath}`, }) else uni.navigateTo({ url: `/${item.pagePath}`, }) return } // proxy.$refs.alert.open() } /** * 内容 * @param {Object} ev */ function handleAlert(ev) { const index = ev.detail.index const item = showMenu.value[index] // 验证 util.isAuth({ success: rs => { // if (item.url) { uni.navigateTo({ url: item.url, }) } else util.alert('敬请期待') } }) // proxy.$refs.alert.close() } </script> <template> <!-- 幽灵盒子 --> <view class="ghost" :style="{paddingBottom: safeHeight}"></view> <!-- 底部导航 --> <view class="menuBox" :class="subject"> <view class="menu"> <view class="item" v-for="(item,index) in menu" :key="index" @click="handleMenu(item)"> <view class="option" :class="{active: item.page === page}" v-if="item.type == 'option'"> <text class="text">{{item.name}}</text> </view> <view class="middle" v-else-if="item.type === 'middle'"> <image class="img" src="/static/footerMenuPlus.png" mode="aspectFit" v-if="subject == 'dark'" /> <image class="img" src="/static/footerMenuPlus1.png" mode="aspectFit" v-else-if="subject == 'light'" /> </view> </view> </view> <view class="safeArea" :style="{height: safeHeight}"></view> <!-- 底部菜单 --> <uni-popup ref="alert" type="bottom"> <view class="alert mlr50 pt50 plr10 pb10"> <scroll-view scroll-y="true" class="scroll"> <uni-grid :column="4" :highlight="true" :showBorder="false" @change="handleAlert"> <uni-grid-item v-for="(item, index) in showMenu" :index="index" :key="index"> <view class="itemBox ptb30 df fdc jcc aic tac"> <image class="wh80" :src="item.img" mode="aspectFill" /> <view class="mt5"> <text class="text f28 c333">{{item.name}}</text> </view> </view> </uni-grid-item> </uni-grid> </scroll-view> <view class="tac mt30"> <uni-icons type="bottom" size="50rpx" color="#999" @click="$refs.alert.close()" /> </view> </view> </uni-popup> </view> </template> <style lang="scss"> // 幽灵盒子 .ghost { height: 120rpx; } // 菜单 .menuBox { position: fixed; left: 0; right: 0; bottom: 0; /* #ifndef APP-NVUE */ box-sizing: border-box; /* #endif */ .menu { justify-content: space-between; padding: 20rpx 0; /* #ifndef APP-NVUE */ display: flex; /* #endif */ /* #ifdef APP-NVUE */ flex-direction: row; /* #endif */ } .item { /* #ifndef APP-NVUE */ display: flex; /* #endif */ align-items: center; justify-content: center; flex: 1; } // 黑色的 &.dark { border-top: 1rpx solid #999; background-color: #161616; .active { .text { color: #fff; } } .text { color: #999; } } // 浅色的 &.light { box-shadow: 0px 8px 20px rgba(0, 0, 0, .3); background-color: #fff; .active { .text { color: #333; } } .text { color: #999; } } .middle { .img { width: 80rpx; height: 80rpx; } } } // 弹窗 .alert { margin-bottom: 120rpx; background-color: #f8f8f8; border-radius: 30rpx; // 滚动块 .scroll { height: 350rpx; } // .itemBox { // padding: 30rpx; } } </style>