<template>
<div>
<div>
<div ref="menuWrapper">
<ul>
<li v-for="(item,index) in goods" :class="{'current':currentIndex===index}" @click="selectMenu(index,$event)" ref="menuList">
<span class="text border-1px">
<span v-show="item.type>0" :class="classMap[item.type]"></span>{{item.name}}
</span>
</li>
</ul>
</div>
<div ref="foodsWrapper">
<ul>
<li v-for="item in goods" ref="foodList">
<h1>{{item.name}}</h1>
<ul>
<li v-for="food in item.foods" class="food-item border-1px">
<div>
<img width="57" height="57" :src="food.icon">
</div>
<div>
<h2>{{food.name}}</h2>
<p>{{food.description}}</p>
<div>
<span>月售{{food.sellCount}}份</span><span>好评率{{food.rating}}%</span>
</div>
<div>
<span>¥{{food.price}}</span><span v-show="food.oldPrice">¥{{food.oldPrice}}</span>
</div>
</div>
</li>
</ul>
</li>
</ul>1
</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
import BScroll from 'better-scroll';
const ERR_OK = 0;
export default {
props: {
seller: {
type: Object
}
},
data() {
return {
goods: [],
listHeight: [],
scrollY: 0
};
},
computed: {
currentIndex() {
for (let i = 0; i < this.listHeight.length; i++) {
let height1 = this.listHeight[i];
let height2 = this.listHeight[i + 1];
if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) {
this._followScroll(i);
return i;
}
}
return 0;
}
},
created() {
this.classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee'];
this.$http.get('/api/goods').then((response) => {
response = response.body;
if (response.errno === ERR_OK) {
this.goods = response.data;
this.$nextTick(() => {
this._initScroll();
this._calculateHeight();
});
}
});
},
methods: {
selectMenu(index, event) {
if (!event._constructed) {
return;
}
let foodList = this.$refs.foodList;
let el = foodList[index];
this.foodsScroll.scrollToElement(el, 300);
},
_initScroll() {
this.meunScroll = new BScroll(this.$refs.menuWrapper, {
click: true
});
this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {
click: true,
probeType: 3
});
this.foodsScroll.on('scroll', (pos) => {
this.scrollY = Math.abs(Math.round(pos.y));
if (pos.y <= 0) {
this.scrollY = Math.abs(Math.round(pos.y));
}
});
},
_calculateHeight() {
let foodList = this.$refs.foodsWrapper;
let height = 0;
this.listHeight.push(height);
for (let i = 0; i < foodList.length; i++) {
let item = foodList[i];
height += item.clientHeight;
this.listHeight.push(height);
}
},
_followScroll(index) {
let menuList = this.$refs.menuList;
let el = menuList[index];
this.meunScroll.scrollToElement(el, 300, 0, -100);
}
}
};
</script>
<style type="text/stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixin.styl";
.goods
display: flex
position: absolute
top: 174px
bottom: 46px
width: 100%
overflow: hidden
.menu-wrapper
flex: 0 0 80px
width: 80px
background: #f3f5f7
.menu-item
display: table
height: 54px
width: 56px
padding: 0 12px
line-height: 14px
&.current
position: relative
z-index: 10
margin-top: -1px
background: #fff
font-weight: 700
.text
border-none()
.icon
display: inline-block
vertical-align: top
width: 12px
height: 12px
margin-right: 2px
background-size: 12px 12px
background-repeat: no-repeat
&.decrease
bg-image('decrease_3')
&.discount
bg-image('discount_3')
&.guarantee
bg-image('guarantee_3')
&.invoice
bg-image('invoice_3')
&.special
bg-image('special_3')
.text
display: table-cell
width: 56px
vertical-align: middle
border-1px(rgba(7, 17, 27, 0.1))
font-size: 12px
.foods-wrapper
flex: 1
.title
padding-left: 14px
height: 26px
line-height: 26px
border-left: 2px solid #d9dde1
font-size: 12px
color: rgb(147, 153, 159)
background: #f3f5f7
.food-item
display: flex
margin: 18px
padding-bottom: 18px
border-1px(rgba(7, 17, 27, 0.1))
&:last-child
border-none()
margin-bottom: 0
.icon
flex: 0 0 57px
margin-right: 10px
.content
flex: 1
.name
margin: 2px 0 8px 0
height: 14px
line-height: 14px
font-size: 14px
color: rgb(7, 17, 27)
.desc, .extra
line-height: 10px
font-size: 10px
color: rgb(147, 153, 159)
.desc
line-height: 12px
margin-bottom: 8px
.extra
.count
margin-right: 12px
.price
font-weight: 700
line-height: 24px
.now
margin-right: 8px
font-size: 14px
color: rgb(240, 20, 20)
.old
text-decoration: line-through
font-size: 10px
color: rgb(147, 153, 159)
.cartcontrol-wrapper
position: absolute
right: 0
bottom: 12px
</style>所有代码在这儿了
掌握Vue1.0到2.0再到2.5最全版本应用与迭代,打造极致流畅的WebApp
了解课程