| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- <template>
- <Theme>
- <view class="cu-bar tabbar foot ZIndex tabbars">
- <view
- class="action"
- @click="NavChange(item, index)"
- v-for="(item, index) in navList"
- :key="index"
- :data-cur="item.name"
- >
- <!-- 图标和数量显示 -->
- <view class="cuIcon-cu-image _item">
- <view>
- <i
- class="icon-font"
- :class="item.icon"
- :style="
- pageCur == item.name
- ? { color: 'var(--primary)' }
- : { color: '#c3cad9' }
- "
- v-if="item.icon"
- ></i>
- <image
- class="img"
- :src="pageCur == item.name ? item.img_active : item.img"
- mode="heightFix"
- v-else
- ></image>
- </view>
- <!-- 数量徽章 -->
- <view class="entry_num" v-if="item.num > 0">{{ item.num }}</view>
- </view>
- <view :class="pageCur == item.name ? 'tabbar_active' : 'tabbar_item'">
- {{ t(item.title) }}
- </view>
- </view>
- </view>
- </Theme>
- </template>
- <script setup>
- import { onMounted, computed, watch, ref, nextTick } from "vue";
- import { useTabbarStore, useMessageStore, useShopStore } from "@/store";
- // 导入图片资源(保持不变)
- import channel from "@/static/tabbar/channel.png";
- import home from "@/static/tabbar/home.png";
- import home_active from "@/static/tabbar/home_active.png";
- import cart from "@/static/tabbar/cart.png";
- import cart_active from "@/static/tabbar/cart_active.png";
- import ship from "@/static/tabbar/ship.png";
- import ship_active from "@/static/tabbar/ship_active.png";
- import chat from "@/static/tabbar/chat.png";
- import chat_active from "@/static/tabbar/chat_active.png";
- import user from "@/static/tabbar/user.png";
- import user_active from "@/static/tabbar/user_active.png";
- import { t } from "@/locale";
- import { storeToRefs } from "pinia";
- import { query } from "@/utils";
- import { onShow } from "@dcloudio/uni-app";
- const useTabbar = useTabbarStore();
- const useShop = useShopStore();
- const useMessage = useMessageStore();
- const { globalMap } = storeToRefs(useMessage);
- const unreadCount = ref(0);
- // 1. 定义购物车数量计算属性(响应式)
- const cartNum = computed(() => useShop.getCartNum);
- const props = defineProps({
- page: {
- type: String,
- default: "index",
- },
- });
- const emit = defineEmits(["getTabbarHeight"]);
- // 2. 将navList定义为ref响应式数组(关键修改)
- const navList = ref([
- {
- name: "index",
- title: "tabbar.首页",
- img: home,
- img_active: home_active,
- num: 0,
- },
- {
- name: "shop",
- title: "tabbar.购物车",
- img: cart,
- img_active: cart_active,
- num: cartNum.value, // 初始值
- },
- {
- name: "chat",
- title: "tabbar.咨询",
- img: chat,
- img_active: chat_active,
- num: unreadCount.value,
- },
- {
- name: "order",
- title: "tabbar.订单",
- img: ship,
- img_active: ship_active,
- num: 0,
- },
- {
- name: "user",
- title: "tabbar.我的",
- img: user,
- img_active: user_active,
- num: 0,
- },
- ]);
- // 3. 监听cartNum变化,实时更新navList中购物车项的num(关键修改)
- watch(
- cartNum,
- (newNum) => {
- // 找到购物车对应的项并更新数量
- const cartItem = navList.value.find((item) => item.name === "shop");
- if (cartItem) {
- cartItem.num = newNum;
- }
- },
- { immediate: true } // 初始化时立即执行一次
- );
- // 监听咨询消息数量(保持不变)
- watch(
- () => globalMap.value.serviceChannel,
- (newVal) => {
- if (newVal) {
- unreadCount.value = newVal.unreadCount;
- const chatItem = navList.value.find((item) => item.name === "chat");
- if (chatItem) {
- chatItem.num = unreadCount.value;
- }
- }
- },
- { deep: true, immediate: true }
- );
- const pageCur = computed(() => useTabbar.setPageCur);
- const NavChange = (item, index) => {
- if (item.name == pageCur.value) return;
- if (item.name == "shop") {
- uni.switchTab({
- url: `/pages/shop/cart`,
- success: () => {
- useTabbar.getPageCur(item.name);
- useTabbar.getPageIndex(index);
- },
- });
- } else {
- uni.switchTab({
- url: `/pages/${item.name}/index`,
- success: () => {
- useTabbar.getPageCur(item.name);
- useTabbar.getPageIndex(index);
- },
- });
- }
- };
- const getHeight = async () => {
- try {
- const res = await query(".tabbar");
- nextTick(() => {
- emit("getTabbarHeight", res.height);
- });
- } catch (error) {}
- };
- onMounted(() => {
- let num = navList.value.findIndex((item) => item.name == props.page);
- if (num >= 0) {
- useTabbar.getPageCur(props.page);
- }
- });
- onShow(() => {
- setTimeout(() => {
- getHeight();
- }, 200);
- });
- </script>
- <!-- 样式部分保持不变 -->
- <style>
- .ZIndex {
- z-index: 2000;
- bottom: 0;
- }
- /deep/ .cu-bar .content {
- cursor: pointer;
- pointer-events: unset;
- }
- .cu-tag.badge:not([class*="bg-"]) {
- background-color: var(--red) !important;
- color: var(--black);
- position: absolute;
- top: -10rpx;
- right: 32%;
- }
- </style>
- <style lang="less" scoped>
- @import "@/static/css/theme.less";
- @import url("@/style.less");
- .tabbar {
- background-color: var(--light);
- bottom: 0;
- }
- .action {
- display: flex !important;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- }
- ._item {
- width: max-content !important;
- position: relative;
- .icon-font {
- font-size: 24px;
- }
- ._item {
- height: 24px;
- vertical-align: top;
- }
- .entry_num {
- position: absolute;
- top: -12rpx;
- right: -14rpx;
- background-color: var(--danger);
- border: 1px solid var(--light);
- color: var(--light);
- width: 36rpx;
- height: 36rpx;
- border-radius: 50%;
- .size(18rpx);
- .flex_center();
- }
- }
- .tabbar_item {
- color: var(--text-01);
- font-size: 10px;
- line-height: 12px;
- margin: 2px auto 0;
- }
- .tabbar_active {
- font-size: 10px;
- line-height: 12px;
- margin: 2px auto 0;
- color: var(--text-02);
- }
- .foot {
- box-shadow: 0 -4px 6px #0000000d;
- }
- .cont_num {
- position: absolute;
- @width: 32rpx;
- width: @width;
- height: @width;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- color: var(--light);
- background-color: var(--red);
- font-size: 24rpx;
- z-index: 2;
- right: -18rpx;
- top: -6rpx;
- }
- </style>
|