|
|
@ -3,10 +3,10 @@ |
|
|
<div class="top f-bb-gray"> |
|
|
<div class="top f-bb-gray"> |
|
|
<img src="../assets/images/icon/arrow-left.png" v-on:click="goBack"/>商品分类 |
|
|
<img src="../assets/images/icon/arrow-left.png" v-on:click="goBack"/>商品分类 |
|
|
</div> |
|
|
</div> |
|
|
<div class="content cate-content"> |
|
|
|
|
|
<div class="left"> |
|
|
|
|
|
|
|
|
<div class="content"> |
|
|
|
|
|
<div class="left" ref="menuWrapper"> |
|
|
<ul> |
|
|
<ul> |
|
|
<li v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" :class="{ on : isActive === index}" @click="jump(index)"> |
|
|
|
|
|
|
|
|
<li v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" :class="{'on': currentIndex === index}" @click="selectMenu(index,$event)"> |
|
|
<a href="javascript:void(0)"> |
|
|
<a href="javascript:void(0)"> |
|
|
{{item.combinationName}} |
|
|
{{item.combinationName}} |
|
|
<img src="../assets/images/icon/hot.png" class="i-hot" v-if="item.label == '2'" /> |
|
|
<img src="../assets/images/icon/hot.png" class="i-hot" v-if="item.label == '2'" /> |
|
|
@ -14,55 +14,68 @@ |
|
|
</a> |
|
|
</a> |
|
|
</li> |
|
|
</li> |
|
|
</ul> |
|
|
</ul> |
|
|
</div> |
|
|
|
|
|
<div class="cate-list right" :scrollTop.prop="scrollTop"> |
|
|
|
|
|
<div v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" class="cate-item"> |
|
|
|
|
|
<p class="title" :id="'anchor-'+index">{{item.combinationName}}</p> |
|
|
|
|
|
<div class="f-relative f-all-1px" v-for="(goods,k) in item.goodsList" :key="k"> |
|
|
|
|
|
<div class="item f-flex"> |
|
|
|
|
|
<a :href="'/mall/web/vgoods/detail/' + goods.goodsNo"> |
|
|
|
|
|
<img :src=" imghost + goods.bannerImgs" class="thumb"/> |
|
|
|
|
|
</a> |
|
|
|
|
|
<div class="info f-flex"> |
|
|
|
|
|
<div> |
|
|
|
|
|
<p class="title f-ellipsis-1">{{goods.name}}</p> |
|
|
|
|
|
<p class="rule">{{goods.shortDesc}}</p> |
|
|
|
|
|
<div class="full" v-if="toJSON(goods.smallLabel)"><i>{{toJSON(goods.smallLabel)}}</i></div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="f-flex"> |
|
|
|
|
|
<p class="price"> |
|
|
|
|
|
<span><span class="money">¥</span>{{goods.price/100}}</span> |
|
|
|
|
|
</p> |
|
|
|
|
|
<p class="cost" v-if="goods.originalPrice">¥{{goods.originalPrice/100}}</p> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="right" ref="foodWrapper"> |
|
|
|
|
|
<div> |
|
|
|
|
|
<div v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" class="food-list-hook"> |
|
|
|
|
|
<p class="title">{{item.combinationName}}</p> |
|
|
|
|
|
<div class="f-relative f-all-1px" v-for="(goods,k) in item.goodsList" :key="k"> |
|
|
|
|
|
<div class="item f-flex"> |
|
|
|
|
|
<a :href="'/mall/web/vgoods/detail/' + goods.goodsNo"> |
|
|
|
|
|
<img :src=" imghost + goods.bannerImgs" class="thumb"/> |
|
|
|
|
|
</a> |
|
|
|
|
|
<div class="info f-flex"> |
|
|
|
|
|
<div> |
|
|
|
|
|
<p class="title f-ellipsis-1">{{goods.name}}</p> |
|
|
|
|
|
<p class="rule">{{goods.shortDesc}}</p> |
|
|
|
|
|
<div class="full" v-if="toJSON(goods.smallLabel)"><i>{{toJSON(goods.smallLabel)}}</i></div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="f-flex"> |
|
|
|
|
|
<p class="price"> |
|
|
|
|
|
<span><span class="money">¥</span>{{goods.price/100}}</span> |
|
|
|
|
|
</p> |
|
|
|
|
|
<p class="cost" v-if="goods.originalPrice">¥{{goods.originalPrice/100}}</p> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<!-- Loading --> |
|
|
<!-- Loading --> |
|
|
<div class="Loading-box"> |
|
|
|
|
|
<loading v-model="showLoading" text="loading"></loading> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<loading :show="showLoading" text="loading"></loading> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
<script> |
|
|
<script> |
|
|
import goodsApi from "../models/goods-model.js"; |
|
|
import goodsApi from "../models/goods-model.js"; |
|
|
import { Alert,Toast,Popup,Loading } from "vux"; |
|
|
import { Alert,Toast,Popup,Loading } from "vux"; |
|
|
|
|
|
import BScroll from 'better-scroll'; |
|
|
export default { |
|
|
export default { |
|
|
data() { |
|
|
data() { |
|
|
return { |
|
|
return { |
|
|
no: 0, |
|
|
no: 0, |
|
|
id: 0, |
|
|
id: 0, |
|
|
c_no: 0, |
|
|
c_no: 0, |
|
|
showLoading: true, |
|
|
|
|
|
|
|
|
showLoading: false, |
|
|
goodsList: [], |
|
|
goodsList: [], |
|
|
imghost: "http://medou.oss-cn-shenzhen.aliyuncs.com/", |
|
|
imghost: "http://medou.oss-cn-shenzhen.aliyuncs.com/", |
|
|
isActive: '', |
|
|
|
|
|
container: document.querySelectorAll('.cate-list') |
|
|
|
|
|
|
|
|
listHeight: [], //存储区块的高度 |
|
|
|
|
|
scrollY: {} |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
computed: { |
|
|
|
|
|
currentIndex () { |
|
|
|
|
|
const { scrollY, listHeight } = this |
|
|
|
|
|
let index = listHeight.findIndex((height, index) => { |
|
|
|
|
|
return scrollY >= listHeight[index] && scrollY < listHeight[index + 1] |
|
|
|
|
|
}) |
|
|
|
|
|
if (scrollY > listHeight[index] + 50) { |
|
|
|
|
|
index++ |
|
|
|
|
|
} |
|
|
|
|
|
return index |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
components: { |
|
|
components: { |
|
|
Toast, |
|
|
Toast, |
|
|
Popup, |
|
|
Popup, |
|
|
@ -96,47 +109,7 @@ |
|
|
this.$vux.toast.text(res.msg,"middle"); |
|
|
this.$vux.toast.text(res.msg,"middle"); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
this.$nextTick(function(){ |
|
|
|
|
|
for (let i = 0; i < this.goodsList.length; i++) { |
|
|
|
|
|
if(this.goodsList[i].combinationNo == this.c_no) { |
|
|
|
|
|
this.jump(i) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
}, |
|
|
jump(index){ |
|
|
|
|
|
const cateItem = document.querySelectorAll('.cate-item'); |
|
|
|
|
|
let total = cateItem[index].offsetTop; |
|
|
|
|
|
let distance = this.container.scrollTop // 获取到顶部的距离(this.container便是.cate-list,为了方便存起来了) |
|
|
|
|
|
let step = total / 20; |
|
|
|
|
|
this.isActive = index; // 菜单列表显示当前样式 |
|
|
|
|
|
const _this = this; |
|
|
|
|
|
if (total > distance) { |
|
|
|
|
|
smoothDown() |
|
|
|
|
|
} else { |
|
|
|
|
|
let newTotal = distance - total |
|
|
|
|
|
step = newTotal / 50 |
|
|
|
|
|
smoothUp() |
|
|
|
|
|
} |
|
|
|
|
|
function smoothDown () { |
|
|
|
|
|
if (distance < total) { |
|
|
|
|
|
distance += step |
|
|
|
|
|
_this.scrollTop = distance - 60 |
|
|
|
|
|
setTimeout(smoothDown, 10); |
|
|
|
|
|
} else { |
|
|
|
|
|
_this.scrollTop = total - 60 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
function smoothUp () { |
|
|
|
|
|
if (distance > total) { |
|
|
|
|
|
distance -= step |
|
|
|
|
|
_this.scrollTop = distance - 60 |
|
|
|
|
|
setTimeout(smoothUp, 10) |
|
|
|
|
|
} else { |
|
|
|
|
|
_this.scrollTop = total - 60 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
toJSON (data){ |
|
|
toJSON (data){ |
|
|
if (data){ |
|
|
if (data){ |
|
|
return JSON.parse(data)[0].labelText |
|
|
return JSON.parse(data)[0].labelText |
|
|
@ -144,54 +117,56 @@ |
|
|
return ; |
|
|
return ; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
onScroll () { |
|
|
|
|
|
var _this = this; |
|
|
|
|
|
_this.itemVal.forEach(function(obj, i){ |
|
|
|
|
|
_this.scrollTop = _this.container.scrollTop; |
|
|
|
|
|
if(_this.scrollTop >= obj.top && _this.scrollTop < (obj.top + obj.height-10)){ |
|
|
|
|
|
// scrollTop的移动位置要在类别的菜品列表中才显示对应锚点的当前状态 |
|
|
|
|
|
_this.isActive = obj.index; |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
_initScroll() { |
|
|
|
|
|
this.menuScroll = new BScroll(this.$refs.menuWrapper,{ |
|
|
|
|
|
click:true //允许better-scroll列表上的点击事件 |
|
|
|
|
|
}); |
|
|
|
|
|
this.foodsScroll = new BScroll(this.$refs.foodWrapper,{ |
|
|
|
|
|
click:true, //允许better-scroll列表上的点击事件 |
|
|
|
|
|
probeType : 3 //让better-scroll监听scroll事件 |
|
|
|
|
|
}); |
|
|
|
|
|
this.foodsScroll.on('scroll', (pos) => { |
|
|
|
|
|
this.scrollY = Math.abs(Math.round(pos.y)); |
|
|
|
|
|
}) |
|
|
}, |
|
|
}, |
|
|
currentStick () { |
|
|
|
|
|
const {dishId} = this.$route.query; |
|
|
|
|
|
const cateContent = document.querySelectorAll('.cate-content'); |
|
|
|
|
|
const _this = this; |
|
|
|
|
|
cateContent.forEach(function(v, i){ |
|
|
|
|
|
if(v.id == dishId){ |
|
|
|
|
|
_this.scrollTop = v.offsetTop; |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
scroll () { |
|
|
|
|
|
// 监听scroll事件 |
|
|
|
|
|
const _this = this; |
|
|
|
|
|
setTimeout(function(){ |
|
|
|
|
|
_this.currentStick(); |
|
|
|
|
|
const rightItem = document.querySelectorAll('.cate-item'); |
|
|
|
|
|
const catelist = document.querySelectorAll('.cate-list')[0]; |
|
|
|
|
|
var length = rightItem.length; |
|
|
|
|
|
var height = rightItem[length-1].offsetHeight; |
|
|
|
|
|
var scrollHeight = document.querySelectorAll('.cate-menu-wrapper')[0].offsetHeight; |
|
|
|
|
|
// 设置最后一个类别菜品列表的高度(小于适配器高度的话与适配器等高),不然点击锚点不能够置顶 |
|
|
|
|
|
if (height < scrollHeight) { |
|
|
|
|
|
rightItem[length-1].style.height = scrollHeight+'px'; |
|
|
|
|
|
} |
|
|
|
|
|
var arr =[]; |
|
|
|
|
|
rightItem.forEach(function(v, i){ |
|
|
|
|
|
arr.push({top: v.offsetTop, height: v.offsetHeight, index: i}); |
|
|
|
|
|
}) |
|
|
|
|
|
_this.itemVal = arr; |
|
|
|
|
|
const cateList = document.querySelectorAll('.cate-list')[0]; |
|
|
|
|
|
cateList.addEventListener('scroll', _this.onScroll); |
|
|
|
|
|
_this.container = cateList; |
|
|
|
|
|
}, 500) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
_calculateHeight() { |
|
|
|
|
|
//food-list-hook类的添加知识为了能拿到food列表,例如,拿到的是多个类似整个粥品的区块 |
|
|
|
|
|
let foodList = this.$refs.foodWrapper.getElementsByClassName("food-list-hook"); |
|
|
|
|
|
let height = 0; |
|
|
|
|
|
this.listHeight.push(height); |
|
|
|
|
|
//listHeight是一个递增的区间数组,是每个专区高度的累加 |
|
|
|
|
|
for (let i = 0; i < foodList.length; i++) { |
|
|
|
|
|
let item = foodList[i]; |
|
|
|
|
|
height += item.clientHeight; |
|
|
|
|
|
this.listHeight.push(height); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
selectMenu(index, event) { |
|
|
|
|
|
if(event && !event._constructed) { |
|
|
|
|
|
return ; |
|
|
|
|
|
} |
|
|
|
|
|
let foodList = this.$refs.foodWrapper.getElementsByClassName("food-list-hook"); |
|
|
|
|
|
let el = foodList[index]; |
|
|
|
|
|
this.foodsScroll.scrollToElement(el,300) |
|
|
|
|
|
}, |
|
|
|
|
|
autoSelect() { |
|
|
|
|
|
for (let i = 0; i < this.goodsList.length; i++) { |
|
|
|
|
|
if(this.goodsList[i].combinationNo == this.c_no) { |
|
|
|
|
|
this.selectMenu(i) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
mounted() { |
|
|
mounted() { |
|
|
this.getParams() |
|
|
this.getParams() |
|
|
this.scroll() |
|
|
|
|
|
|
|
|
window.onload = () =>{ |
|
|
|
|
|
//调用scroll函数,实现滚动 |
|
|
|
|
|
this._initScroll() |
|
|
|
|
|
//拿到数据以后计算高度 |
|
|
|
|
|
this._calculateHeight(); |
|
|
|
|
|
// 自动选中 |
|
|
|
|
|
this.autoSelect() |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
} |
|
|
} |
|
|
</script> |
|
|
</script> |
|
|
@ -219,11 +194,13 @@ |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
display: flex; |
|
|
display: flex; |
|
|
height: calc(100vh - 0.9rem); |
|
|
height: calc(100vh - 0.9rem); |
|
|
|
|
|
-webkit-overflow-scrolling: touch; |
|
|
.left { |
|
|
.left { |
|
|
width: 1.74rem; |
|
|
width: 1.74rem; |
|
|
background-color: #F3F3F3; |
|
|
background-color: #F3F3F3; |
|
|
overflow-y: auto; |
|
|
overflow-y: auto; |
|
|
overflow-x: hidden; |
|
|
overflow-x: hidden; |
|
|
|
|
|
-webkit-overflow-scrolling: touch; |
|
|
ul { |
|
|
ul { |
|
|
li { |
|
|
li { |
|
|
width: 1.74rem; |
|
|
width: 1.74rem; |
|
|
@ -259,6 +236,7 @@ |
|
|
.right { |
|
|
.right { |
|
|
overflow-y: auto; |
|
|
overflow-y: auto; |
|
|
overflow-x: hidden; |
|
|
overflow-x: hidden; |
|
|
|
|
|
-webkit-overflow-scrolling: touch; |
|
|
padding: 0.2rem 0.22rem 0; |
|
|
padding: 0.2rem 0.22rem 0; |
|
|
width: calc(100% - 1.74rem); |
|
|
width: calc(100% - 1.74rem); |
|
|
box-sizing: border-box; |
|
|
box-sizing: border-box; |
|
|
@ -324,16 +302,4 @@ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
.Loading-box { |
|
|
|
|
|
.weui-toast { |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
min-height: 100% !important; |
|
|
|
|
|
overflow: hidden; |
|
|
|
|
|
top: 0; |
|
|
|
|
|
} |
|
|
|
|
|
.weui-icon_toast.weui-loading { |
|
|
|
|
|
margin-top: 75%; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
</style> |
|
|
</style> |