<view class="goods-box">
<scroll-view scroll-y="true" class="classify" :scroll-top="scrollTop" scroll-with-animation>
<view class="classify-item" :class="categoryIndex===index?'active':''" v-for="(item,index) in categoryList" :key="item.id" @tap="categoryClick(item,index)">
<image class="icon u-m-r-4" :src="item.image" mode="aspectFill" v-if="item.image"></image>{{item.name}}</view>
</scroll-view>
</view>
data() {
return {
categoryList: [],
categoryIndex: 0, // 当前选中的分类索引
scrollTop: 0, // 用于控制 scroll-view 的滚动位置
classifyRect: {},
}
},
getGoodsCategoryList() {
this.$http({
url: 'api/web/getGoodsCategoryList',
}).then(res => {
this.categoryList = res.data.data; // 获取分类数据
// 确保 DOM 已渲染完成,进行 DOM 查询
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this); // 在当前页面上下文中创建选择器查询
query.select('.classify').boundingClientRect(); // 查询 scroll-view 的位置和尺寸
query.selectAll('.classify-item').boundingClientRect(); // 获取分类项的位置
query.exec(queryRes => {
this.classifyRect = queryRes[0]
// 将查询结果添加到 categoryList 中
if (queryRes && queryRes[1]) {
// 将 DOM 数据与 categoryList 合并
this.categoryList.forEach((item, index) => {
const rect = queryRes[1][index]; // 获取每个分类项的位置信息
item.rect =
rect; // 把分类项的位置数据添加到 categoryList 对应的 item 中
});
}
});
});
});
},
categoryClick(item, index) {
this.categoryIndex = index; // 更新当前选中的分类索引
// 如果 item 不包含位置信息,动态查询该项的位置
if (!item.rect.top || !item.rect.height) {
const query = uni.createSelectorQuery().in(this);
query.select('.classify-item').eq(index).boundingClientRect(); // 获取当前点击项的位置
query.exec(res => {
if (res && res[0]) {
item.rect.top = res[0].top;
item.rect.height = res[0].height;
this.scrollToCategory(item); // 获取位置数据后,再调用滚动操作
}
});
} else {
// 如果 item 已经包含位置信息,直接调用滚动
this.scrollToCategory(item);
}
},
// 单独提取滚动操作逻辑
scrollToCategory(item) {
const scrollViewHeight = this.classifyRect.height;
const scrollViewTop = this.classifyRect.top; // scroll-view 距离页面顶部的位置
const itemTop = item.rect.top - scrollViewTop; // 分类项相对 scroll-view 的位置
const itemHeight = item.rect.height; // 当前点击项的高度
const targetScrollTop = itemTop - (scrollViewHeight / 2) + (itemHeight / 2);
this.scrollTop = targetScrollTop; // 设置 scrollTop,滚动到目标位置
}