vue_qsw_fk_web/src/components/goods/goods.vue

257 lines
6.9 KiB
Vue

<template lang="html">
<div class="goods">
<div class="menu-wrapper" ref="menuWrapper">
<ul>
<li v-for="(item,index) in goods" @click="menuClick(index,$event)" :class="index==menuCurrentIndex?'menu-item-selected':'menu-item'">
<span class="text">
<iconMap v-show="item.type>0" :iconType="item.type"></iconMap>
{{item.name}}
</span>
</li>
</ul>
</div>
<div class="foods-wrapper" id="wrapper" ref="foodsWrapper">
<ul>
<li v-for="item in goods" class="food-list food-list-hook">
<h1>{{item.name}}</h1>
<ul>
<li v-for="food in item.foods" class="food-item" @click="goDetail(food)">
<div class="icon">
<img width="57" height="57" :src="food.icon"/>
</div>
<div class="content">
<h2>{{food.name}}</h2>
<p class="description" v-show="food.description">{{food.description}}</p>
<div class="sell-info">
<span class="sellCount">月售{{food.sellCount}}份</span>
<span class="rating">好评率{{food.rating}}%</span>
</div>
<div class="price">
<span class="newPrice"><span class="unit">¥</span>{{food.price}}</span>
<span v-show="food.oldPrice" class="oldPrice">¥{{food.oldPrice}}</span>
</div>
<div class="cartcontrol-wrapper">
<cartcontrol :food="food"></cartcontrol>
</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
<shopCart :deliveryPrice="seller.deliveryPrice" :minPrice = "seller.minPrice" :selectFoods="selectFoods"></shopCart>
<foodDetail :food="selectedFood" v-if="selectedFood" ref="myFood"></foodDetail>
</div>
</template>
<script>
import iconMap from 'components/iconMap/iconMap'
import BScroll from 'better-scroll'
import shopCart from 'components/shopCart/shopCart'
import cartcontrol from 'components/cartcontrol/cartcontrol'
import foodDetail from 'components/foodDetail/foodDetail'
import axios from 'axios'
import Vue from 'vue'
const ERR_OK = 0
const eventHub = new Vue()
export default {
props: {
seller: Object
},
created() {
axios.get('static/data.json').then((res) => {
this.goods = res.data.goods
this.$nextTick(() => {
this._initScroll(); // 初始化scroll
this._calculateHeight(); // 初始化列表高度列表
})
});
},
data() {
return {
goods: [],
listHeight: [],
foodsScrollY: 0,
selectedFood: ''
}
},
computed: {
menuCurrentIndex() {
for (let i = 0, l = this.listHeight.length; i < l; i++) {
let topHeight = this.listHeight[i]
let bottomHeight = this.listHeight[i + 1]
if (!bottomHeight || (this.foodsScrollY >= topHeight && this.foodsScrollY < bottomHeight)) {
return i
}
}
return 0
},
selectFoods() {
let foods = []
this.goods.forEach((good) => {
good.foods.forEach((food) => {
if (food.count) {
foods.push(food)
}
})
})
return foods
}
},
methods: {
_initScroll() {
this.menuWrapper = new BScroll(this.$refs.menuWrapper, {
click: true
});
this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {
click: true,
probeType: 3
});
// 监控滚动事件
this.foodsScroll.on('scroll', (pos) => {
this.foodsScrollY = Math.abs(Math.round(pos.y))
})
},
_calculateHeight() {
let foodList = this.$refs.foodsWrapper.querySelectorAll('.food-list-hook')
let height = 0
this.listHeight.push(height)
for (let i = 0, l = foodList.length; i < l; i++) {
let item = foodList[i]
height += item.clientHeight
this.listHeight.push(height)
}
},
menuClick(index, event) {
if (!event._constructed) {
return
}
this.foodsScroll.scrollTo(0, -this.listHeight[index], 300)
},
goDetail(food) {
this.selectedFood = food
this.$nextTick(() => {
this.$refs.myFood.showToggle()
})
}
},
components: {
iconMap,
shopCart,
cartcontrol,
foodDetail
}
}
</script>
<style lang="stylus">
@import '../../common/stylus/mixin'
.goods
display flex
position absolute
top 174px
bottom 46px
width 100%
overflow hidden
.menu-wrapper
flex 0 0 80px
width 80px
background #F3F5BD
margin-top: 2px;
.menu-item-selected
background white
font-weight 700
margin-top -1px
.menu-item,.menu-item-selected
position relative
display table
height 54px
line-height 14px
width 56px
padding 0 12px
&:last-child:after
content none
.menu-item:after
position: absolute
content: ''
left: 12px
width: 56px
bottom: 0
border-bottom: 1px solid rgba(7,17,27,0.1)
.text
display table-cell
vertical-align middle
font-size 12px
font-weight 200
white-space normal
line-height 14px
.iconMap
vertical-align middle
.foods-wrapper
flex 1
margin-top: 2px;
.food-list
h1
height 26px
line-height 26px
padding-left 12px
font-size 12px
color rgb(147,153,159)
background #f3f5f7
border-left 2px solid #d9dde1
.food-item
position relative
display flex
margin: 0 18px;
padding: 18px 0;
border-bottom 1px solid rgba(7,17,27,0.1)
.icon
flex 0 0 57px
&:last-child
border-bottom none
.content
flex 1
padding-left 10px
h2
margin 2px 0 8px 0
font-size 14px
line-height 14px
height 14px
font-weight 700
color rgb(7,17,27)
.sell-info,.description
font-size 10px
color rgb(147,153,159)
line-height 10px
.sellCount
margin-right 4px
.description
font-size 10px
margin-bottom 8px
line-height: 12px
.price
font-size 10px
font-weight 700
line-height 24px
.newPrice
font-size 14px
color rgb(240,20,20)
.unit
font-size 10px
font-weight normal
.oldPrice
text-decoration line-through
color rgb(147,153,159)
padding-left 4px
.cartcontrol-wrapper
position: absolute
right: 0
bottom 12px
z-index 20
</style>