mrr.sj.front/components/tabbar/tabbar.vue

183 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<uv-tabbar
v-if="tabbarReady"
:key="refreshKey"
fixed
:value="currentTabIndex"
@change="onTabChange"
activeColor="#FF4767"
:placeholder="false"
:safeAreaInsetBottom="false"
:customStyle="{height:'110rpx'}"
>
<uv-tabbar-item
v-for="(item, idx) in tabbarList"
:key="idx"
:name="idx"
:text="item.text"
:badge="getNum(idx)"
:customStyle="{height:'110rpx'}"
@click="onItemClick(idx)"
>
<template v-slot:active-icon>
<image class="icon" :src="item.selectedIconPath"></image>
</template>
<template v-slot:inactive-icon>
<image class="icon" :src="item.iconPath"></image>
</template>
</uv-tabbar-item>
</uv-tabbar>
</template>
<script>
import { mapState, mapMutations } from 'vuex';
import request from "@/utils/request";
export default {
name: "tab-bar",
// 不再需要 props.selected完全由 Vuex 控制高亮
data() {
return {
refreshKey: 0, // 强制重建标识
tabbarReady: false, // 组件就绪标识
tabbarList: [ // tab 配置
{
iconPath: "/static/images/tabbar/new_home_gray.png",
text: "首页",
selectedIconPath: "/static/images/tabbar/new_home.png",
pagePath: "/pages/home/home"
},
{
iconPath: "/static/images/tabbar/new_order_gray.png",
text: "订单",
selectedIconPath: "/static/images/tabbar/new_order.png",
pagePath: "/pages/order/all-orders"
},
{
iconPath: "/static/images/tabbar/new_message_gray.png",
text: "消息",
selectedIconPath: "/static/images/tabbar/new_message.png",
pagePath: "/pages/message/message"
},
{
iconPath: "/static/images/tabbar/new_my_gray.png",
text: "我的",
selectedIconPath: "/static/images/tabbar/new_my.png",
pagePath: "/pages/my/my"
}
]
};
},
computed: {
// 从 Vuex 获取全局高亮索引
...mapState(['currentTabIndex', 'messageNum'])
},
watch: {
// 当 tabbarList 内容变化(如异步更新图标)时,强制重建组件
tabbarList: {
deep: true,
handler() {
this.rebuildTabbar();
}
}
},
created() {
// 初始化时延迟显示,避免闪烁
this.tabbarReady = false;
this.$nextTick(() => {
this.tabbarReady = true;
// 如果需要异步加载图标,取消下面注释
// this.getButtonImg();
});
},
methods: {
...mapMutations(['SET_CURRENT_TAB_INDEX']),
// 设置全局选中索引(简化调用)
setCurrentTabIndex(index) {
this.SET_CURRENT_TAB_INDEX(index);
},
// 强制重建 uv-tabbar用于异步更新图标后
rebuildTabbar() {
this.tabbarReady = false;
this.$nextTick(() => {
this.refreshKey++;
this.tabbarReady = true;
});
},
// 获取角标数字(只有消息 tab 且数量 > 0 才显示)
getNum(index) {
if (index === 2 && this.messageNum > 0) {
return this.messageNum;
}
return null;
},
// 异步更新图标(保留你的业务逻辑)
async getButtonImg() {
try {
let res = await request.post("/sj/poster/getButtonImg", {});
if (res.code === 200) {
this.tabbarList.forEach((item, index) => {
if (res.data[index]?.iconPath) {
item.iconPath = res.data[index].iconPath;
}
if (res.data[index]?.selectedIconPath) {
item.selectedIconPath = res.data[index].selectedIconPath;
}
});
this.$store.commit("setTabbarList", this.tabbarList);
// 图标更新后,强制重建组件
this.rebuildTabbar();
}
} catch (err) {
console.error('getButtonImg 请求失败', err);
}
},
// uv-tabbar 的 change 事件(组件内部触发)
onTabChange(val) {
const idx = parseInt(val, 10);
this.doJump(idx);
},
// 手动点击 item 时触发
onItemClick(idx) {
this.doJump(idx);
},
// 实际跳转逻辑 + 更新全局高亮
doJump(index) {
const idx = parseInt(index, 10);
if (isNaN(idx) || !this.tabbarList[idx]) return;
// 先更新全局高亮(立即生效)
this.setCurrentTabIndex(idx);
// 跳转页面
const targetPage = this.tabbarList[idx].pagePath;
uni.switchTab({
url: targetPage,
fail: (err) => console.error('switchTab 失败', err)
});
// 保留你原有的消息更新方法
if (typeof this.messageUpudateNum === 'function') {
this.messageUpudateNum();
}
}
}
};
</script>
<style lang="scss">
.icon {
height: 54rpx;
width: 54rpx;
}
::v-deep .uv-tabbar__content {
z-index: 999 !important;
}
</style>