New file |
| | |
| | | <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> |