绿满眶商城微信小程序-uniapp
zxl
2025-06-26 3bff34c3aa7ad412042272ea6a37b7d5b49b8d9b
components/TopBar.vue
New file
@@ -0,0 +1,147 @@
<template>
   <view class="top-bar" :style="{paddingTop: statusBarHeight + 'px'}">
      <view class="top-bar-content">
         <!-- 标题列表 -->
         <scroll-view class="title-scroll" scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
            <view class="title-container">
               <view
                  v-for="(item, index) in titleList"
                  :key="index"
                  :class="{active: selectedTitleIndex === item.index, 'title-item': true}"
                  :style="{color: textColor}"
                  @click="changeTab(item)"
               >
                  <text>{{item.title}}</text>
                  <view class="underline" :style="{backgroundColor: textColor}" v-if="selectedTitleIndex === item.index"></view>
               </view>
            </view>
         </scroll-view>
      </view>
   </view>
</template>
<script>
   export default {
      name:"TopBar",
      props: {
         selectedTitleIndex: {
            type: String,
            default: 'home'
         },
         textColor: {
            type: String,
            default: 'white'
         }
      },
      data() {
         return {
            statusBarHeight: 0,
            scrollLeft: 0,
            titleList: [
               {
                  index: 'home',
                  pagePath: '/pages/tabbar/index/home',
                  title: '推荐'
               },
               {
                  index: 'shop',
                  pagePath: '/pages/commodity-square/commoditySquare',
                  title: '商品广场'
               },
               {
                  index: 'activity',
                  pagePath: '/pages/mine/activity/reportActivity',
                  title: '活动'
               },
               {
                  index: 'health',
                  pagePath: '/pages/health/healthVideo',
                  title: '大健康'
               }
            ]
         };
      },
      created() {
         // 获取状态栏高度
         const systemInfo = uni.getSystemInfoSync();
         this.statusBarHeight = systemInfo.statusBarHeight;
      },
      methods: {
         changeTab(titleObj) {
            console.log("点击顶部导航", titleObj);
            if (titleObj.index !== this.selectedTitleIndex) {
               this.$emit("changeTab", titleObj);
               // 计算滚动位置使当前选中项居中
               this.$nextTick(() => {
                  const query = uni.createSelectorQuery().in(this);
                  query.select(`.title-item[data-index="${titleObj.index}"]`).boundingClientRect();
                  query.select('.title-scroll').boundingClientRect();
                  query.exec(res => {
                     if (res[0] && res[1]) {
                        const itemLeft = res[0].left;
                        const scrollWidth = res[1].width;
                        const itemWidth = res[0].width;
                        this.scrollLeft = itemLeft - (scrollWidth - itemWidth) / 2;
                     }
                  });
               });
            }
         }
      }
   }
</script>
<style>
   .top-bar {
         position: fixed;
         top: 0;
         left: 0;
         right: 0;
         z-index: 999;
      }
      .top-bar .top-bar-content {
         box-sizing: border-box;
         display: flex;
         align-items: center;
      }
      .top-bar .title-scroll {
         width: 100%;
         height: 80rpx;
         white-space: nowrap;
      }
      .top-bar .title-scroll .title-container {
         display: inline-flex;
         height: 100%;
         align-items: center;
      }
      .top-bar .title-scroll .title-container .title-item {
         position: relative;
         padding: 0 24rpx;
         font-size: 32rpx;
         /* color: white; */
         height: 100%;
         display: flex;
         align-items: center;
         justify-content: center;
         flex-direction: column;
      }
      .top-bar .title-scroll .title-container .title-item.active {
         font-weight: 500;
      }
      .top-bar .title-scroll .title-container .title-item.active .underline {
         position: absolute;
         bottom: 4rpx;
         left: 50%;
         transform: translateX(-50%);
         width: calc(100% - 76rpx);
         height: 4rpx;
         /* background-color: white; */
         border-radius: 4rpx;
      }
</style>