先把页面分成左右两部分,左边部分为商品分类,右边为每个商品类别的相关商品
<view class="cates">
<SearchInput></SearchInput> // 此为我自定义组件,为一个搜索框
<view class="cates_container">
<scroll-view scroll-with-animation="{{true}}" scroll-y="{{true}}" class="leftMenuList">
// 点击后class加入active
<view class="menu_item {{index==currentIndex?'active':''}}"
wx:for="{{leftMenuList}}"
wx:for-item="leftItem"
wx:key="menuIndex"
bindtap="handleItemTap"
data-index = "{{index}}"
data-menuIndex="{{leftItem.menuIndex}}">{{leftItem.name}}</view>
</scroll-view>
<scroll-view scroll-top="{{scrollTop}}"
scroll-with-animation="{{true}}"
scroll-y="{{true}}"
class="rightMenuContent"
scroll-into-view="{{toTitle}}"
bindscroll="scrollToLeft"> // scroll-into-view定位
<view class="rightGroup"
wx:for="{{rightMenuContent}}"
wx:for-item="rightItem"
wx:key="menuIndex" id="right-{{rightItem.menuIndex}}">
<view class="goods_title">
<text class="delimiter">/</text>
<view class="title">{{rightItem.name}}</view>
<text class="delimiter">/</text>
</view>
<view class="goods_list">
<navigator wx:for="{{rightItem.good_list}}" wx:for-item="goodItem" wx:key="name">
<image mode="widthFix" src="{{goodItem.good_img}}" />
<view class="goods_name">{{goodItem.good_name}}</view>
</navigator>
</view>
</view>
</scroll-view>
</view>
</view>
wxml
<view class="search_input">
<navigator url="../../pages/search/index" open-type="navigate">
搜索
</navigator>
</view>
less
.search_input {
height: 90rpx;
padding: 10rpx;
background-color: var(--themeColor); // 此为自定义颜色
navigator {
display: flex;
justify-content: center;
background-color: #fff;
align-items: center;
height: 100%;
border-radius: 15rpx;
color: #666;
}
}
新建一个app.wxss的文件
@import "./styles/iconfont.wxss" // 一个图标文件
page {
--themeColor: #eb4450;
}
page {
height: 100%;
}
.cates {
height: 100%;
.cates_container {
height: ~'calc( 100vh - 90rpx )'; // 注意写法:计算屏幕总高度减去上下两个固定组件的高度
display: flex;
.leftMenuList {
flex: 2;
.menu_item {
width: 200rpx;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 30rpx;
}
.active {
color: var(--themeColor);
border-left: 5rpx solid currentColor;
}
}
.rightMenuContent {
flex: 5;
.rightGroup {
.goods_title {
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
.delimiter {
color: #ccc;
padding: 0 10rpx;
}
}
.goods_list {
display: flex;
flex-wrap: wrap;
navigator {
width: 33.33%;
text-align: center;
margin-bottom: 40rpx;
image {
height: 100rpx;
width: 100rpx;
}
.goods_name {
font-size: 25rpx;
}
}
}
}
}
}
}
Page({
data: {
leftMenuList: [ // 自行添加n个类似内容
{
name: "热门推荐",
menuIndex: 'a'
}
],
rightMenuContent: [
{ // 自行添加n个类似内容
name: "热门推荐",
menuIndex: 'a',
good_list: [ // 自行添加n个类似内容
{
good_name: "手机",
good_img: "http://image2.suning.cn/uimg/cms/img/153684246313252041.png"
}
]
}
],
toTitle: "",
currentIndex: 0,
scrollTop: 0,
top: []
},
// 此方法为点击左边商品栏,自动定位到右边相应的商品展示(关键点为在右边商品栏的scroll-view内
添加一个scroll-into-view="{{toTitle}}")
handleItemTap(e) {
const menuindex = e.currentTarget.dataset.menuindex;
const index = e.currentTarget.dataset.index;
this.setData({
currentIndex: index,
toTitle: "right-" + menuindex
})
},
// 此方法为右边商品栏滚动,自动定位到左边商品栏的分类
scrollToLeft(res) {
this.setData({
scrollTop: res.detail.scrollTop
})
let length = this.data.top.length // 此方法为onload方法计算每个右边分类栏的所在高度
for (let i = 0; i < this.data.top.length; i++) {
// 当某个商品栏所在高度减去第一个商品栏所在高度大于等于当前滚动高度,且小于下一个商品栏所在高度减
第一个商品栏所在高度,且该商品栏不为最后一个商品栏(最后一个没有下一个)
if(this.data.top[i] - this.data.top[0] <= this.data.scrollTop && i<length-1 && this.data.top[i+1] - this.data.top[0] > this.data.scrollTop){
if(this.data.currentIndex != i) {
this.setData({
currentIndex: i
})
}
}
}
},
// 加载每个商品栏所在高度
onLoad: function (options) {
var that = this
wx.getSystemInfo({
success: function(res) {
var top2 = []
// console.log(that.data.leftMenuList[0].menuIndex);
for(let i=0;i<that.data.leftMenuList.length;i++){
// 重中之重
wx.createSelectorQuery().select("#right-" + that.data.leftMenuList[i].menuIndex).boundingClientRect().exec(function(res){
var numTop = res[0].top
top2.push(numTop)
})
}
that.setData({
top: top2
})
}
})
},
})
还有一些地方没有做好,一个就是左边栏超出后,当右边滚动,左边会定位但是不会滚动。