Files
2025-06-09 17:48:23 +08:00

242 lines
6.2 KiB
Vue

<template>
<view class="content" :style="{ top: top + 'rpx' }">
<!-- 左边tab栏开始 -->
<scroll-view class="left" scroll-with-animation="all 0.2s ease" :scroll-into-view="toLeftId" scroll-y>
<view
:upper-threshold="500"
:id="`l_id${index}`"
v-for="(item, index) in lists"
:key="index"
class="item text-center"
:class="{ active: index == currentId }"
@click="handleSelect(index)"
>
{{ item.title }}
<view class="cuIconlujing226"></view>
</view>
</scroll-view>
<!-- 左边tab栏结束 -->
<!-- 右边列表开始 -->
<scroll-view
class="right"
scroll-with-animation="all 0.2s ease"
refresher-background="transparent"
scroll-y
@scroll="scroll"
:scroll-top="scrollTop"
:refresher-triggered="refresherTriggered"
:refresher-enabled="true"
:refresher-threshold="100"
@refresherrefresh="refresherrefresh"
>
<view class="cate-box-wrap" v-for="(item, index) in lists" :key="index">
<view class="flex align-center justify-between text-333">
<text class="cate-box-wrap-title text-bold text-df">{{ item.title }}</text>
</view>
<view class="cate-box">
<view class="cate-box-item" v-for="(ele, j) in item.son_list" :key="j" @tap.stop="handlerClassify(ele, item)">
<image style="width: 80rpx; height: 80rpx" :src="ele.thumb" mode="aspectFill" />
<text class="text-333 text-sm goods_title">{{ ele.title }}</text>
</view>
</view>
</view>
</scroll-view>
<!-- 右边列表结束 -->
</view>
</template>
<script>
export default {
name: 'benben-goods-classify',
props: {
// 分类列表
lists: {
type: Array,
default: () => [],
},
top: {
type: [Number, String],
default: 88,
},
handleId: {
type: [Number, String],
default: '',
},
},
data() {
return {
refresherTriggered: false,
heightArr: [],
flag: false,
setTimeoutFn: null,
setTimeoutLists: null,
scrollTop: '',
toLeftId: '',
currentId: 0, //选中id
setTimeoutHandle: null,
}
},
watch: {
lists: {
handler() {
this.setTimeoutLists && clearTimeout(this.setTimeoutLists)
this.setTimeoutLists = setTimeout(this.getHeight, 300)
},
deep: true,
immediate: true,
},
},
components: {},
computed: {},
onLoad() {},
mounted() {},
methods: {
refresherrefresh() {
this.refresherTriggered = true
setTimeout(() => {
this.refresherTriggered = false
this.$emit('refresh')
}, 500)
},
scroll(e) {
this.setTimeoutFn && clearTimeout(this.setTimeoutFn)
this.setTimeoutFn = setTimeout(() => {
let height = e.target.scrollTop
console.log(height, '~~~~~~~~~~');
let index = this.heightArr.findIndex((item) => height >= item.minHeight && height < item.maxHeight)
console.log(index, '~~~~~~~~~~index');
this.currentId = index == -1 ? 0 : index
this.toLeftId = `l_id${index >= 3 ? index - 3 : 0}`
}, 100)
},
/**
* @event
* @description tab切换
* @param {Number} item -当前选中数据 //暂时没用
* @param {Number} index - 选中下标
* @return {Boolean}
* */
handleSelect(index) {
console.log(index, '选中左侧');
let randomInt = Math.floor(Math.random() * 11);
let scrollTop = this.heightArr[index].minHeight > 0 ? this.heightArr[index].minHeight + 10 : 0
this.scrollTop = scrollTop + (randomInt * 0.001)
console.log(this.scrollTop, '选中左侧滚动高度');
},
handlerClassify(item, pitem) {
this.$emit('update:handle-id', item.aid)
this.$emit('handle-item', item, pitem)
},
getHeight() {
uni
.createSelectorQuery()
.in(this)
.selectAll('.cate-box-wrap')
.boundingClientRect()
.exec((res) => {
console.log('~~~~~~~~~~~~~~~~')
console.log(res)
let heightArr = []
let height = 0
res[0].map((item, index) => {
let obj = { minHeight: height > 0 ? height : height }
// height += Math.floor(item.height)
height = (item.bottom).toFixed(2) - 0
obj.maxHeight = height
heightArr.push(obj)
})
console.log(heightArr)
this.heightArr = heightArr
})
},
},
}
</script>
<style lang="scss" scoped>
.title {
background-color: #fff;
text-align: center;
font-size: 36rpx;
color: #333;
font-weight: 500;
}
.goods_title {
width: 146rpx;
overflow: hidden; //超出的文本隐藏
text-overflow: ellipsis; //用省略号显示
white-space: nowrap; //不换行
}
.content {
border-top: 1px solid #f8f8f8;
position: fixed;
bottom: var(--window-bottom);
display: flex;
.left {
width: 180rpx;
height: 100%;
background-color: #f8f8f8;
box-sizing: border-box;
.item {
width: 100%;
height: 99rpx;
line-height: 99rpx;
font-size: 28rpx;
color: #333;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
}
.item.active {
// background-color: #fff;
color: #FF9300;
font-weight: bold;
position: relative;
&::before {
content: '';
width: 8rpx;
height: 34rpx;
background: #FF9300;
border-radius: 4rpx;
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
}
}
}
.right {
width: 570rpx;
height: 100%;
background-color: #f8f8f8;
}
}
.cate-box-wrap {
margin-right: 20rpx;
margin-bottom: 10px;
border-radius: 12rpx;
background-color: #fff;
.cate-box-wrap-title {
line-height: 80rpx;
padding: 0 32rpx;
}
&:last-child {
// min-height: calc(100vh - var(--window-bottom) - var(--window-top));
min-height: 100%;
}
.cate-box {
display: flex;
flex-wrap: wrap;
.cate-box-item {
display: flex;
flex-direction: column;
align-items: center;
width: 33%;
text-align: center;
padding-bottom: 20rpx;
}
}
}
</style>