页面大致
页面布局
<!--pages/shop/index.wxml-->
<view class="wrap">
<view class="shop-search">
<view class="search-box">
<image src="/images/search.png"></image>
<input class="text-light-gray" value="请输入关键字……" disabled="true" bindtap="gotoSearch"></input>
</view>
<view class="shop-cart" bindtap="gotoCart">
<image src="/images/cart.png"></image>
<view class="cart-num"><point num="{
{cartNumber}}"></point></view>
</view>
</view>
<view class="shop-list">
<view class="shop-list-left">
<block wx:for="{
{navData}}">
<view class="list-left-item {
{activeIndex==index?'list-left-item-active':''}}" bindtap="changeNav" data-id="{
{item.id}}" data-index="{
{index}}">{
{
item.name}}</view>
</block>
</view>
<scroll-view
bindtouchstart="touchstart" bindtouchend="touchend" bindtouchmove="touchmove"
bindtouchcancel="touchcancel"
wx:if="{
{goodsData.length>0}}"
class="shop-list-right"
scroll-y
scroll-top="{
{scroll}}"
scroll-y="true"
upper-threshold="30"
lower-threshold="30"
bindscroll="bindscroll"
bindscrolltoupper="refresh"
bindscrolltolower="loadMore"
>
<view wx:if="{
{!slide_s && activeIndex !=0}}" class="list_item_slide">下拉继续浏览{
{
navData[activeIndex-1].name}}</view>
<block wx:for="{
{goodsData}}" wx:key="i">
<view class="list-right-item" data-id="{
{item.id}}" bindtap="gotoDetails">
<view class="right-item-img">
<image src="{
{item.image!=''?item.image:'/images/no_pic.png'}}" mode="aspectFit" lazy-load='true'></image>
</view>
<view class="right-item-info">
<view class="item-info-til font-small">【美汁源果粒橙】1.8L</view>
<view class="item-info-sales"><text class="font-bigger text-red">¥48.00</text>
<text class="font-mini text-light-gray">已售:999份 </text>
</view>
<view class="item-info-msg font-mini text-light-gray">
<text>999条评价</text>
<text>好评率:99%</text>
</view>
</view>
</view>
</block>
<view class="list_item_slide2">
<text wx:if="{
{!slide_x && activeIndex + 1 != navData.length}}">加载中...</text>
</view>
</scroll-view>
<view
bindtouchstart="touchstart" bindtouchend="touchend" bindtouchmove="touchmove"
bindtouchcancel="touchcancel"
class="shop-list-right flex" wx:else>
<!-- wx:if="{
{!slide && activeIndex !=0}}" -->
<view wx:if="{
{!slide_s && activeIndex !=0}}" class="list_item_slide1">下拉继续浏览{
{
navData[activeIndex-1].name}}</view>
<image class="no-data" src="/images/no_data2.png"></image>
<view wx:if="{
{!slide_x && activeIndex + 1 != navData.length}}" class="list_item_slide3">加载中...</view>
</view>
</view>
</view>
css
/**shop.wxss**/
/* 商城搜索样式 */
.shop-search{
overflow: hidden;
padding: 25rpx;
display: flex;
}
.search-box{
flex: 1;
height:58rpx;
background:rgba(245,245,245,1);
border-radius:30rpx;
padding-left: 28rpx;
display: flex;
align-items: center;
}
.search-box image{
width: 30rpx;
height: 30rpx;
margin-right: 18rpx;
}
.search-box input{
flex: 1;
font-size: 20rpx;
}
.shop-cart{
position: relative;
margin-right: 18rpx;
margin-left: 36rpx;
display: flex;
align-items: center;
}
.shop-cart image{
width: 34rpx;
height: 34rpx;
}
.shop-cart .cart-num{
position: absolute;
right: 2rpx;
top:15rpx;
}
/* 商城首页列表样式*/
.shop-list{
flex: 1;
display: flex;
}
.shop-list-left,.shop-list-right{
max-height: 100%;
overflow: auto;
}
.shop-list-left{
width: 163rpx;
margin-right: 42rpx;
background:rgba(250,250,250,1);
}
.list-left-item{
line-height: 85rpx;
height: 85rpx;
text-align: center;
}
.list-left-item-active{
color: #F22510;
background: #fff;
}
.shop-list-right{
flex: 1;
}
.list-right-item{
padding: 36rpx 0;
overflow: hidden;
border-bottom: 2rpx solid #f5f5f5;
display: flex;
}
.right-item-img{
width: 180rpx;
display: flex;
align-items:center;
}
.right-item-img image{
width: 100%;
height: 180rpx;
}
.right-item-info{
flex: 1;
margin-left: 18rpx;
margin-right: 25rpx;
}
.item-info-til{
color:rgba(51,51,51,1);
width: 100%;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.item-info-type{
background:linear-gradient(135deg,rgba(248,65,76,1) 0%,rgba(224,82,33,1) 100%);
border-radius:4rpx;
width:56rpx;
color:#fff;
text-align: center;
font-size: 18rpx;
}
.item-info-sales,.item-info-msg{
display: flex;
line-height: 52rpx;
}
.item-info-sales .font-mini,.item-info-msg text:last-child{
flex: 1;
text-align: right;
}
.item-info-msg{
line-height: 30rpx;
}
/* */
.no-data{
width: 188rpx;
height: 188rpx;
margin: 0 auto;
}
.discuss-pic{
width:181rpx;
height:181rpx;
border-radius: 10rpx;
margin-right: 36rpx;
}
/* */
.font30{
font-size: 30rpx;
}
/*商品详情页底部固定条*/
.shop-details-fixed{
position: fixed;
bottom: 0;
left: 0;
width: 100vmin;
height: 112rpx;
background: #fff;
box-shadow:0px -1px 2px 0px rgba(0,0,0,0.18);
}
.btn-box .btn{
float: right;
width: 182rpx;
height: 62rpx;
line-height: 62rpx;
text-align: center;
border-radius: 30rpx;
margin-right: 20rpx;
}
.buyBtn{
margin-right: 27rpx;
background:linear-gradient(135deg,#F77300 0%,#F22510 100%);
box-shadow:0px -1px 2px 0px #F77300;
}
.addBtn{
background:linear-gradient(135deg,#FFD94C 0%,#FFB919 100%);
box-shadow:0px -1px 2px 0px #FFD94C;
}
/* 购物车列表、、、下单列表 */
.cart-list{
background: #fff;
padding: 0 34rpx;
}
.list-item{
padding: 36rpx 0;
border-bottom: 2rpx solid #eee;
}
.item-img,.item-img image{
width:181rpx;
height:181rpx;
border-radius: 10rpx;
}
.item-info,.item-info-sales .price-cut{
flex: 1;
}
.item-info-sales{
padding-top: 52rpx;
}
/* 商品评价 */
/* */
.shop-detail-discuss{
overflow: hidden;
padding: 0;
background: #fff;
}
.discuss-til{
padding: 8rpx 20rpx 16rpx;
}
.discuss-til .discuss-til-left{
flex: 1;
padding-left: 30rpx;
position: relative;
}
.discuss-til-left::before{
position: absolute;
content: '';
left:0;
top:50%;
width: 12rpx;
height: 34rpx;
background: #F7231F;
margin-top: -17rpx;
}
.discuss-til-left text{
padding-left: 10rpx;
font-weight: 400;
}
.discuss-til-right{
margin: 0 8rpx;
}
.discuss-til-right image{
width: 10rpx;
height: 16rpx;
margin-left: 20rpx;
}
/* */
.logo{
width: 92rpx;
height: 92rpx;
border-radius: 50%;
margin-right: 18rpx;
}
.discuss-item-info,.discuss-item-info text:first-child{
flex: 1;
}
.discuss-item{
border-bottom: 18rpx solid #FAFAFA;
padding-top: 0;
}
.discuss-item-info {
line-height: 26rpx;
padding: 16rpx 0;
}
.discuss-item-info .flex{
margin-bottom: 10rpx;
}
.discuss-item-center{
margin: 25rpx 0;
line-height:30rpx;
width: 100%;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.discuss-item-pic{
overflow: hidden;
padding-bottom: 26rpx;
}
/* pages/shop/index.wxss */
/* page{
height: 100vmax;
} */
.wrap{
display: flex;
flex-direction: column;
height: 100vmax;
background: #fff;
}
/* */
.shop-scroll{
width: 100vmin;
height: 322rpx;
background: pink;
}
/* */
.item-info-sales .text-gray {
padding-left: 12rpx;
}
/* .item-info-sales .price-cut:last-child .price-first{
font-size: 24rpx;
} */
.shop-list-right{
position: relative;
}
.list_item_slide,.list_item_slide1{
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
color: rgba(200, 200, 200, 1);
animation: list_item_slide 0.3s ease-in-out ;
}
.list_item_slide1{
position: absolute;
top: 0;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
color: rgba(200, 200, 200, 1);
animation: list_item_slide 0.3s ease-in-out ;
}
.list_item_slide2{
width: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
z-index: 3001;
color: rgba(200, 200, 200, 1);
margin-top: 10rpx;
margin-bottom: 40rpx;
animation: list_item_slide 0.3s ease-in-out ;
}
.list_item_slide3{
position: absolute;
bottom: 0;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
z-index: 3001;
color: rgba(200, 200, 200, 1);
margin-bottom: 5rpx;
animation: list_item_slide 0.3s ease-in-out ;
}
@keyframes list_item_slide {
0% {
transform: translateY(-5px);
opacity: 0;
}
/* 50% {
transform: translateY(0);
opacity: 1;
} */
100% {
transform: translateY(0);
opacity: 1;
}
}
js
// pages/shop/index.js
const app = getApp()
const urls = require('../../utils/link.js')
var t
Page({
/**
* 页面的初始数据
*/
data: {
navData: [{
"id": 12,
"name": "零食乳饮",
"sort": 4
}, {
"id": 13,
"name": "米面粮油",
"sort": 3
}, {
"id": 14,
"name": "洗护美妆",
"sort": 2
}],
activeIndex:0,
goodsData:[
], // 当前显示的数组
goodsTotal:[
[{
"id": 29,
"name": "【美汁源果粒橙】1.8L",
"type": "自营",
"image": "",
"group_id": 12
}, {
"id": 30,
"name": "【蒙牛纯牛奶】250ml*24",
"type": "自营",
"image": "",
"group_id": 12
}, {
"id": 32,
"name": "【娃哈哈AD钙奶】220g*24瓶",
"type": "自营",
"image": "",
"group_id": 12
}, {
"id": 27,
"name": "八宝粥",
"type": "自营",
"image": "",
"group_id": 12
},
],[ {
"id": 32,
"name": "【娃哈哈AD钙奶】220g*24瓶",
"type": "自营",
"image": "",
"group_id": 13
}, {
"id": 27,
"name": "八宝粥",
"type": "自营",
"image": "",
"group_id": 13
},{
"id": 32,
"name": "【娃哈哈AD钙奶】220g*24瓶",
"type": "自营",
"image": "",
"group_id": 13
}, {
"id": 27,
"name": "八宝粥",
"type": "自营",
"image": "",
"group_id": 13
},{
"id": 32,
"name": "【娃哈哈AD钙奶】220g*24瓶",
"type": "自营",
"image": "",
"group_id": 13
}, {
"id": 27,
"name": "八宝粥",
"type": "自营",
"image": "",
"group_id": 13
}, ],
], // 暂存的数据
cartNumber:0,
isVip:2,
scrollTop: 0, // 储存滚动位置
slide: true, // 当前是否可以拖动 默认为真
slide_s: true, // 上方
slide_x: true, // 下方
scroll: 0, // 滑动距离
scroll_top: true, // 是否滑动到了顶部
down: false, // 是否滑动到了底部
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// this.getData();
this.setData({
goodsData: this.data.goodsTotal[0]
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
// if(app.globalData.userInfo){
// this.cartNumber();
// }
},
onReady: function () {
},
//切换商品分类
changeNav(e,item){
// 此处为 切换 分类&导航
// 并进行遍历 查看是否储存本地缓存
let that=this;
let _dat = {
};
if(e != null){
_dat = e.currentTarget.dataset;
}else{
_dat = item;
}
// console.log(_dat)
let _id = _dat.id;
let _index=_dat.index;
that.setData({
activeIndex:_index,
groupId: _id,
});
let goodsData = [];
let _goodsTotal = that.data.goodsTotal;
let Len = _goodsTotal.length; //
// that.getGoods();
// console.log(_goodsTotal.length ,that.data.goodsTotal,that.data.navData)
if (Len < that.data.navData.length){
if(_goodsTotal.length > 0){
}else{
that.getGoods();
return
}
for (let i = 0; i < Len;i++){
if (_goodsTotal[i] ){
if (_id == _goodsTotal[i][0].group_id) {
goodsData = _goodsTotal[i]
}
}
}
}else{
console.log(2)
for (let i = 0; i < Len; i++) {
if (_goodsTotal[i].length > 0) {
if (_id == _goodsTotal[i][0].group_id) {
goodsData = _goodsTotal[i]
}
}else{
that.getGoods();
}
}
}
if(goodsData.length > 0){
//
this.setData({
goodsData: goodsData
})
setTimeout(()=>{
this.setData({
slide: true,
slide_s: true,
slide_x: true,
scroll_top: true,
down: false,
scroll: 0,
scrollTop: 0,
})
},200)
}else{
// 如果为空 说明此 数组 没有数据 或者没有获取过
console.log('没有数据 或 没有被获取过');
that.getGoods();
}
},
//获取数据
getData(){
// 获取导航栏
},
//根据群组id获取商品
getGoods(){
// 请求 商品
},
cartNumber(){
let that=this;
app.request(urls.cartNumber, {
}, (res) => {
// 成功
if(res.rc == 200){
that.setData({
cartNumber: res.data.cart_number
});
}else{
}
}, (res) => {
// 失败
}, (res) => {
// 请求结束
})
},
//跳转到详情页
gotoDetails(e){
wx.navigateTo({
url: 'detail/index?id=' + e.currentTarget.dataset.id
})
},
//跳转到查询页面
gotoSearch(){
wx.navigateTo({
url: 'search/index?cartNum=' + this.data.cartNumber
})
},
//跳转到购物车
gotoCart() {
// 检验是否登录
let url = '/pages/shop/index';
let url1 = '/pages/shop/cart/index';
app.loginOfButton(userInfo => {
wx.navigateTo({
url: url1
})
}, url, 2);
},
// 上部下拉
refresh(e){
// console.log(this.data.startX)
// this.setData({
// startX: e.changedTouches[0].clientX,
// startY: e.changedTouches[0].clientY,
// })
},
// 底部上拉
loadMore(e){
this.setData({
down: true
})
},
//手指触摸动作开始 记录起点X坐标
touchstart: function (e) {
this.setData({
startX: e.changedTouches[0].clientX,
startY: e.changedTouches[0].clientY,
})
if(this.data.goodsData.length<3){
this.setData({
scroll_top: true,
down: true,
})
}
console.log('触摸动作开始')
},
//滑动事件处理
touchmove: function (e) {
var that = this,
scroll_top = that.data.scroll_top,
down = that.data.down,
startX = that.data.startX,//开始X坐标
startY = that.data.startY,//开始Y坐标
touchMoveX = e.changedTouches[0].clientX,//滑动变化坐标
touchMoveY = e.changedTouches[0].clientY,//滑动变化坐标
//获取滑动角度
angle = that.angle({
X: startX, Y: startY }, {
X: touchMoveX, Y: touchMoveY });
//滑动超过30度角 return
console.log(angle,1111)
if(!this.data.slide) return; // 不为真
if (Math.abs(angle) < 45) return;
if (touchMoveY > startY ){
console.log('上滑')
this.setData({
down: false
})
}
if (touchMoveY > startY && scroll_top){
// console.log('上滑')
this.setData({
slide: false,
slide_s: false,
down: false
})
} else if(down){
// 下滑
console.log('下滑')
this.setData({
slide: false,
slide_x: false,
})
}
// if (touchMoveY > startY){
// // console.log('上滑')
// this.slide(1);
// } else { // 下滑
// // console.log('下滑')
// this.slide(2);
// }
// if (Math.abs(angle) > 30) return;
// if (touchMoveX > startX) //右滑
// console.log('右滑')
// else //左滑
// console.log('左滑')
},
// 滑动结束
touchend(e){
// console.log(e)
var that = this,
scroll_top = that.data.scroll_top,
down = that.data.down,
startX = that.data.startX,//开始X坐标
startY = that.data.startY,//开始Y坐标
touchMoveX = e.changedTouches[0].clientX,//滑动变化坐标
touchMoveY = e.changedTouches[0].clientY,//滑动变化坐标
//获取滑动角度
angle = that.angle({
X: startX, Y: startY }, {
X: touchMoveX, Y: touchMoveY });
//滑动超过30度角 return
// console.log(Math.abs(angle),1111)
// if(!this.data.slide) return; // 不为真
if (Math.abs(angle) < 45) return;
console.log(touchMoveY,startY,)
if (touchMoveY > startY) {
this.setData({
down: false
})
}
if (touchMoveY > startY && scroll_top){
// console.log('上滑')
this.slide(1);
} else if(down){
// 下滑
// console.log('下滑')
this.slide(2);
}
// if (Math.abs(angle) > 30) return;
// if (touchMoveX > startX) //右滑
// console.log('右滑')
// else //左滑
// console.log('左滑')
},
// 手指触摸动作被打断
touchcancel(e){
this.setData({
slide: true, // 当前是否可以拖动 默认为真
slide_s: true, // 上方
slide_x: true, // 下方
scroll: 0, // 滑动距离
scrollTop: 0,
scroll_top: true, // 是否滑动到了顶部
down: false, // 是否滑动到了底部
})
},
// 滑动
slide(type){
console.log(type)
// clearTimeout(t);
clearInterval(t);
let item = {
},
navData = this.data.navData,
activeIndex = this.data.activeIndex,
length = this.data.navData.length;
if(type == 1){
this.setData({
slide: false,
slide_s: false,
})
}else{
this.setData({
slide: false,
slide_x: false,
})
}
t = setTimeout(()=>{
if(type == 1 && activeIndex !=0){
console.log('夏花')
item = {
id : navData[activeIndex - 1].id,
index: activeIndex - 1,
}
this.changeNav(null,item)
}else if(type == 2 && activeIndex + 1 != length){
console.log("赏花")
item = {
id : navData[activeIndex + 1].id,
index: activeIndex + 1,
}
this.changeNav(null,item)
}else{
this.setData({
slide: true,
slide_s: true,
slide_x: true,
})
}
},300)
},
/**
* 计算滑动角度
* @param {Object} start 起点坐标
* @param {Object} end 终点坐标
*/
angle: function (start, end) {
var _X = end.X - start.X,
_Y = end.Y - start.Y
//返回角度 /Math.atan()返回数字的反正切值
// console.log(360 * Math.atan(_Y / _X) / (2 * Math.PI))
return 360 * Math.atan(_Y / _X) / (2 * Math.PI);
},
//监听屏幕滚动 判断上下滚动
bindscroll(e){
// 406
// console.log(e,1547 - 1194)
// console.log(e)
let scroll_top = true;
let scrollTop = this.data.scrollTop;
if(e.detail.scrollTop>30){
scroll_top = false;
}else{
scroll_top = true;
}
// console.log(scrollTop ,e.detail.scrollTop,'000000000000')
if(scrollTop > e.detail.scrollTop){
// 说明是向上方滚动,向下方拉动 // 解决上拉商品列表至底部,再下拉错误加载下一导航问题;
// console.log(1111111111)
this.setData({
down: false,
})
}
this.setData({
scroll_top: scroll_top,
scrollTop: e.detail.scrollTop,
})
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})