seller详情页最上面是overview部分,其中overview下面的三等分的内容,用ul,li的列表结构来实现,布局用flex来实现
<ul class="remark">
<li class="block">
<h2>起送价</h2>
<div class="content">
<span class="stress">{{seller.minPrice}}</span>元
</div>
</li>
<li class="block">
<h2>商家配送</h2>
<div class="content">
<span class="stress">{{seller.deliveryPrice}}</span>元
</div>
</li>
<li class="block">
<h2>平均配送时间</h2>
<div class="content">
<span class="stress">{{seller.deliveryTime}}</span>分钟
</div>
</li>
</ul>
.remark
display: flex
padding-top: 18px
.block
flex: 1
text-align: center
border-right: 1px solid rgba(7, 17, 27, 0.1)
&:last-child
border: none
h2
margin-bottom: 4px
line-height: 10px
font-size: 10px
color: rgb(147, 153, 159)
.content
line-height: 24px
font-size: 10px
color: rgb(7, 17, 27)
.stress
font-size: 24px
在这个组件里BScroll效果的添加不是在cteated()钩子函数中,在created()钩子函数中不能保证dom已经完成了渲染,我们要确保dom渲染完成之后才能使用。我们使用mounted()钩子函数,这个钩子函数在dom渲染完成之后可以被调用。
watch: {
'seller'() {
this.$nextTick(() => {
this._initScroll();
this._initPics();
});
}
},
mounted() {
this.$nextTick(() => {
this._initScroll();
this._initPics();
});
},
_initScroll() {
if (!this.scroll) {
this.scroll = new BScroll(this.$refs.seller, {
click: true
});
} else {
this.scroll.refresh();
console.log('refresh');
console.log(this.scroll);
}
},
图片的横向滚动也用BScroll实现,要有一个容器div,这个容器设置为固定的宽度,white-space: nowrap 设置图片超出宽度时不换行,overflow: hidden超出的内容不显示。包含图片的li元素设置为display: inline-block。使用BScroll时,内层元素的宽度要大于外层元素的宽度,因此我们需要计算和设置内层元素ul的宽度。
<div class="pic-wrapper" ref="picWrapper">
<ul class="pic-list" ref="picList">
<li class="pic-item" v-for="pic in seller.pics">
<img :src="pic" width="120" height="90">
</li>
</ul>
</div>
_initPics() {
if (this.seller.pics) {
let picWidth = 120;
let margin = 6;
let width = (picWidth + margin) * this.seller.pics.length - margin;
this.$refs.picList.style.width = width + 'px';
this.$nextTick(() => {
if (!this.picScroll) {
this.picScroll = new BScroll(this.$refs.picWrapper, {
scrollX: true,
eventPassthrough: 'vertical'
});
} else {
this.picScroll.refresh();
}
});
}
}
收藏部分采用absolute定位,用一个变量favorite控制爱心是否激活,根据favorite的值改变favoriteText的值,点击事件toggleFavorite会改变favorite的值。
<div class="favorite" @click="toggleFavorite">
<span class="icon-favorite" :class="{'active':favorite}"></span>
<span class="text">{{favoriteText}}</span>
</div>
在App.vue文件中,给seller增加一个id属性,id通过一个立即执行函数从url中获取
data() {
return {
seller: {
id: (() => {
let queryParam = urlParse();
return queryParam.id;
})()
}
};
}
/**
* 解析url参数
* @example ?id=12345&a=b
* @return Object {id:12345,a=b}
*/
export function urlParse() {
let url = window.location.search;
let obj = {};
let reg = /[?&][^?&]+=[^?&]+/g;
let arr = url.match(reg);
// ['?id=12345','&a=b']
if (arr) {
arr.forEach((item) => {
let tempArr = item.substring(1).split('=');
let key = decodeURIComponent(tempArr[0]);
let val = decodeURIComponent(tempArr[1]);
obj[key] = val;
});
}
return obj;
};
localStorage存储和读取的实现
export function saveToLocal(id, key, value) {
let seller = window.localStorage.__seller__;
if (!seller) {
seller = {};
seller[id] = {};
} else {
seller = JSON.parse(seller);
if (!seller[id]) {
seller[id] = {};
}
}
seller[id][key] = value;
window.localStorage.__seller__ = JSON.stringify(seller);
};
export function loadFromLocal(id, key, def) {
let seller = window.localStorage.__seller__;
if (!seller) {
return def;
}
seller = JSON.parse(seller)[id];
if (!seller) {
return def;
}
let ret = seller[key];
return ret || def;
};
用keep-alive可以保留组件的状态,route的时候从内存中回复组件的状态
<keep-alive>
<router-view :seller="seller"></router-view>
</keep-alive>