WXML
<!--pages/menu/menu.wxml-->
<view>
<my-banner swiperArr="{{swiperArr}}"></my-banner> //轮播图组件(代码在底部)
<view class='main'>
//左边的导航栏菜单
<scroll-view class="left" scroll-y="true" scroll-into-view="{{leftId}}">
<view id="left{{item.id}}" data-myid="{{item.id}}" class="scroll-view-item {{item.id==currentNum?'active':''}}"
wx:for="{{menuArr}}" wx:key="*this" bindtap="leftClickfn">{{item.title}}</view>
</scroll-view>
//右边的菜单
<scroll-view class="right" scroll-with-animation="true" scroll-y="true" bindscroll="scroll" scroll-into-view="{{rightId}}" bindscroll="scrollrightFn">
<view id="right{{item.id}}" class="scroll-view-items rightblock" wx:for="{{menuArr}}" wx:key="*this">
<view class="title">{{item.title}}</view>
<view class="content">
<view class="box" wx:for="{{item.subArr}}" wx:key="*this" wx:for-item="items">
<image src="{{items.imgSrc}}" mode="widthFix"></image>
<text>{{items.imgDesc}}</text>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
WXSS
swiper {
//轮播图
height: calc(100vw / 1080 * 520);
}
.main {
/* background-color: pink; */
//当前可视高度减去轮播图的高度
height: calc(100vh - calc(100vw / 1080 * 520));
}
.main .left {
border-right: 1rpx solid #000;
width: 25%;
height: calc(100vh - calc(100vw / 1080 * 520));
box-sizing: border-box;
float: left;
}
.left view {
height: 80rpx;
background-color: #fff;
border-bottom: 1rpx solid #ccc;
line-height: 80rpx;
text-align: center;
position: relative;
}
.left view::before {
content: "";
width: 10rpx;
height: 80rpx;
background-color: #fff;
position: absolute;
left: 0;
top: 0;
}
.left view.active::before {
//当前选中的样式
background-color: #333999;
}
.main .right {
//右边的商品
width: 75%;
float: right;
height: calc(100vh - calc(100vw / 1080 * 520));
padding: 0 2%;
box-sizing: border-box;
}
.right .title {
height: 60rpx;
line-height: 60rpx;
}
.right .content {
background-color: #fff;
padding: 1%;
display: flex;
padding-right: 0;
box-sizing: border-box;
justify-content: flex-start;
flex-wrap: wrap;
}
.box {
width: 32%;
margin-right: 1%;
text-align: center;
margin-bottom: 10rpx;
}
.box image {
width: 90%;
display: block;
margin: 0 auto;
}
.box text {
text-align: center;
font-size: 28rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
display: block;
}
JS
// pages/menu/menu.js
Page({
data: {
//轮播图
swiperArr: ['/images/banner/menubanner1.jpg', '/images/banner/menubanner2.jpg', '/images/banner/menubanner3.jpg'],
//menu
menuArr: [{
"id": 0,
"title": "人气Top",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "桃桃芝士红宝石"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "咖啡风味安慕希"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "陨石拿铁"
}
]
},
{
"id": 1,
"title": "大师咖啡",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "冲绳黑糖拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "陨石拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "拿铁"
}
]
},
{
"id": 2,
"title": "小鹿茶精选",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "标准美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "加浓美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "焦糖标准美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "焦糖加浓拿铁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "银河气泡美式"
}
]
},
{
"id": 3,
"title": "瑞纳冰",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "乐岛桃桃冰"
}]
},
{
"id": 4,
"title": "鲜榨果蔬汁",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "NFC鲜榨橙汁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "NFC鲜榨西柚汁"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "猕猴桃复合果汁"
}
]
},
{
"id": 5,
"title": "经典饮品",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "巧克力"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "纯牛奶"
}
]
},
{
"id": 6,
"title": "健康轻食",
"subArr": [{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "京味烤鸭鲜蔬卷"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "夏威夷菠萝火山卷"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "火腿芝士羊角"
},
{
"imgSrc": "/images/menu/1-1.jpg",
"imgDesc": "鸡肉卷"
}
]
}
],
//左侧id
leftid: 'left0',
//当前项
currentNum: 0,
//右侧id
rightId: 'right0',
//右侧高度的数组
heightArr: []
},
leftClickfn(e) {
//点击左边的导航栏,跳到对应的商品区块
this.setData({
//获取自定义属性data-myid赋值
currentNum: e.currentTarget.dataset.myid,
leftid: 'left' + e.currentTarget.dataset.myid,
rightId: 'right' + e.currentTarget.dataset.myid
})
},
scrollrightFn(e) {
//滑动
let arr = this.data.heightArr;
let st = e.detail.scrollTop;
for (let i = 0; i < arr.length; i++) {
//当前滑动的高度大于数组里的项的时候,进行跳转到对应的商品区块
if (st >= arr[i] && st < arr[i + 1] - 10) {
this.setData({
leftid: 'left' + i,
currentNum: i
})
}
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
//获取每个区块的高度
onReady: function () {
let _this = this;
setTimeout(() => {
let initArr = [0] //初始化数组
let initNum = 0 //初始化数字
const query = wx.createSelectorQuery()
query.selectAll('.rightblock').boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(function (res) {
// console.log(res[0]); //得到每个模块的高度
res[0].map(e => {
initNum += e.height; //每个模块的高度给到初始值
initArr.push(initNum); //添加到数组
})
// console.log(initArr);
_this.setData({
heightArr: initArr
})
})
}, 300);
},
})
附上轮播图的代码:(组件的轮播Components)
WXML
<view>
<swiper autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" bindchange="swiperFn">
<swiper-item wx:for="{{swiperArr}}" wx:key="*this">
<image src="{{item}}" mode="widthFix"></image>
</swiper-item>
</swiper>
</view>
<view class="swiper">
<view class="indicator">
<view wx:for="{{swiperArr}}" wx:key="*this" class="{{index==swiperNum ? 'active' : ''}}"> </view>
</view>
</view>
WXSS
swiper image {
width: 100vw;
}
.swiper{
position: relative;
}
.indicator {
position: absolute;
right: 20rpx;
bottom: 20rpx;
}
.indicator view {
width: 30rpx;
height: 30rpx;
background: #ccc;
border-radius: 30rpx;
float: left;
margin-left: 20rpx;
transition: all 1s linear;
}
.indicator view.active {
width: 50rpx;
background: #34399C;
}
JS
// components/banner/banner.js
Component({
properties: {
swiperArr: {
//定义类型
type: Array,
//定义默认值
value: []
}
},
data: {
autoplay: true,
swiperNum: 0,
interval: 2000,
duration: 500,
},
methods: {
swiperFn(e) {
this.setData({
swiperNum: e.detail.current
})
}
}
})
JSON
{
"usingComponents": {},
"component":true
}
"usingComponents": {
"my-banner":"/components/banner/banner"
},