Files
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

142 lines
2.9 KiB
Vue
Raw Permalink 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>
<view class="category-tabs-container">
<scroll-view
class="category-scroll"
scroll-x
:scroll-left="scrollLeft"
:scroll-with-animation="true"
:show-scrollbar="false"
>
<view class="category-list">
<view
v-for="(category, index) in categories"
:key="category.id"
class="category-item"
:class="{ active: activeCategory?.id === category.id }"
@click="handleCategoryClick(category, index)"
>
<text class="category-name">{{ category.name }}</text>
<view class="category-indicator" v-if="activeCategory?.id === category.id"></view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
name: 'ProjectCategoryTabs',
props: {
// 分类列表
categories: {
type: Array,
default: () => []
},
// 当前选中的分类
activeCategory: {
type: Object,
default: null
}
},
data() {
return {
scrollLeft: 0
}
},
watch: {
activeCategory: {
handler(newVal) {
if (newVal && this.categories.length > 0) {
this.scrollToActiveCategory()
}
},
immediate: true
}
},
methods: {
handleCategoryClick(category, index) {
this.$emit('change', category)
// 滚动到选中的分类
this.scrollToIndex(index)
},
scrollToIndex(index) {
// 计算需要滚动的距离
// 这里简化处理,实际可以根据元素宽度计算
const itemWidth = 120 // 每个分类项的预估宽度(rpx)
const scrollViewWidth = 750 // scroll-view宽度(rpx)
const targetLeft = index * itemWidth - scrollViewWidth / 2 + itemWidth / 2
this.scrollLeft = Math.max(0, targetLeft)
},
scrollToActiveCategory() {
const index = this.categories.findIndex(cat => cat.id === this.activeCategory?.id)
if (index !== -1) {
this.scrollToIndex(index)
}
}
}
}
</script>
<style scoped>
.category-tabs-container {
width: 100%;
background-color: #fff;
border-bottom: 1rpx solid #f0f0f0;
}
.category-scroll {
width: 100%;
white-space: nowrap;
height: 90rpx;
}
.category-list {
display: inline-flex;
align-items: center;
height: 100%;
padding: 0 30rpx;
}
.category-item {
position: relative;
padding: 0 30rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.category-name {
font-size: 30rpx;
color: #666;
font-weight: 400;
transition: all 0.3s ease;
}
.category-item.active .category-name {
color: #3cc51f;
font-weight: 500;
font-size: 32rpx;
}
.category-indicator {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 4rpx;
background-color: #3cc51f;
border-radius: 2rpx;
}
/* 点击效果 */
.category-item:active {
opacity: 0.7;
}
</style>