左側(cè)寬度固定绪杏,右邊自適應(yīng)
flex: 0 0 80px
第一個(gè)是等分,第二個(gè)是縮放雕憔,第三個(gè)是占位空間
<div class="goods">
<div class="menu-wrapper"></div>
<div class="foods-wrapper"></div>
</div>
--------------------css------------------------
.goods
display: flex
position: absolute
top: 174px
bottom: 46px
width: 100%
.menu-wrapper
flex: 0 0 80px
width: 80px
background: #ccc
.foods-wrapper
flex: 1
--------------------js獲取數(shù)據(jù)------------------
const ERR_OK = 0
export default {
props: {
seller: {
type: Object
}
},
data() {
return {
goods: []
}
},
created: {
this.$http.get('/api/goods').then((res) => {
res = res.body
if(res.errno === ERR_OK){
this.goods = res.data
}
})
}
}
左側(cè)布局
可能有多行垂直居中萧吠,適合用display:table
<ul>
<li class="menu-item" v-for="item in goods" >
<span class="text border-1px">
<span v-show="item.type>0" class="icon" :class="classMap[item.type]"></span>
{{ item. name}}
</span>
</li>
</ul>
-------------js----------------------------------------------
export default {
created:() {
this.classMap = ['decrease','discount','special','invoice','guarantee'];
}
}
-------------css----------------------------------------------
bg-image($url)
background-image: url($url + "@2x.png")
@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3)
background-image: url($url + "@3x.png")
.menu-item
display: table
width: 56px
height: 54px
padding: 0 12px
line-height: 14px
.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.2))
font-size: 12px
右側(cè)布局
<div class="foods-wrapper">
<ul>
<li v-for="item in goods" class="food-list">
<h1 class="title">{{ item.name }}</h1>
<ul>
<li v-for="food in item.foods" class="food-item">
<div class="icon">
<img :src="food.icon">
</div>
<div class="content">
<h2 class="name">{{ food.name}}</h2>
<p class="desc">{{food.description}}</p>
<div class="extra">
<span>月售{{ food.sellCount }}份</span>
<span>好評(píng)率{{ food.rating }}%</span>
</div>
<div class="price">
<span>¥{{ food.price }}</span>
<span v-show="food.oldPrice">¥{{ food.oldPrice }}</span>
</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
--------------------------css-------------------------------
.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
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)
怎么把1像素的邊去掉及老?
在mixin.styl中寫(xiě):
border-none()
&:after
display: none
better-scroll應(yīng)用
- 安裝
cnpm install better-scroll --save
- 使用
import BScroll from 'better-scroll'
vue取dom
<div class="menu-wrapper" ref="menuWrapper"></div>
created() {
this.classMap = ['decrease','discount','special','invoice','guarantee'];
this.$http.get('/api/goods').then((res) => {
res = res.body
if(res.errno === ERR_OK){
this.goods = res.data
this.$nextTick(() => {
//this.$nextTick() => 在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個(gè)方法范抓,獲取更新后的 DOM骄恶。
//數(shù)據(jù)發(fā)生變化后,不能直接更新在dom上匕垫,需要在回調(diào)函數(shù)中刷新DOM,即異步加載DOM
this._initScroll()
})
}
})
},
methods: {
_initScroll() {
//this.$refs:取得DOM對(duì)象
this.menuScroll = new BScroll(this.$refs.menuWrapper, {})
this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {})
}
}
如果報(bào)錯(cuò)
Error in nextTick: "TypeError: Cannot read property 'children' of undefined"
那么就是因?yàn)?br>
<div class="menu-wrapper" ref="menuWrapper"></div>
menuWrapper要用駝峰寫(xiě),不要用-
實(shí)現(xiàn)左右聯(lián)動(dòng)
右邊縱坐標(biāo)落到哪個(gè) 區(qū)間僧鲁,計(jì)算每個(gè)區(qū)間的高度
然后返回右邊的索引 與 左邊的索引相等時(shí)栅表,給左側(cè)Li高亮
在`$nextTick`拿到數(shù)據(jù)钾麸,dom更新后
data() {
return {
listHeight: [],
scrollY: 0
}
},
computed: {
currentIndex() {
for(let i = 0; i < listHeight.length; i++){
let height1 = listHeight[i];
let height2 = listHeight[i + 1]
if(!height2 || this.scrollY >= height1 && this.scrollY < height2){
return i
}
}
return 0
}
},
created: {
this.$nextTick(function(){
this._initScroll();
this._calculateHeight();
})
},
methods: {
_initScroll() {
this.menuScroll = new BScroll(this.$refs.menuWrapper, {
click: true //取消默認(rèn)阻止事件
});
this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {
click: true,
probeType: 3 //監(jiān)聽(tīng)事件的觸發(fā)時(shí)間,1為即時(shí)觸發(fā)踱葛,3為延遲觸發(fā)
});
this.foodsScroll.on('scroll', () => {
this.scrollY = Math.abs(Math.round(pos.y))
})
},
_calculateHeight(){
var foodList = this.$refs.foodsWrapper.getElementsByClassName('food-list-hook')
let height = 0
for(var i = 0; i < foodList.length; i++){
let item = foodList[i]//獲取每個(gè)li的高度
height += item.clientHeight;
this.listHeight.push(height);
}
}
}
把右邊當(dāng)前的索引關(guān)聯(lián)到左側(cè)導(dǎo)航的索引
<li v-for="(item,index) in goods" class="menu-item" :class="{'current':currentIndex === index}"></li>
- 點(diǎn)擊左側(cè)菜單 實(shí)現(xiàn)右側(cè)聯(lián)動(dòng)
index:當(dāng)前索引值
$event://當(dāng)pc瀏覽器會(huì)觸發(fā)兩次偶惠,解決方法傳入event
<li v-for="(item,index) in goods" class="menu-item" :class="{'current':currentIndex === index}" @click="selectMenu(index,$event)"></li>
methods: {
selectMenu(index,event) {
if(!event._constructed){//阻止非vue事件
return
}
var foodList = this.$refs.foodsWrapper.getElementsByClassName('food-list-hook');
let el = foodList[index]//獲取右側(cè)當(dāng)前位置
this.foodsScroll.scrollToElement(el, 300)//右側(cè)內(nèi)容指向右側(cè)當(dāng)前位置
}
}