提交 d3599282 编写于 作者: M maguohua

updata

上级 1f190a6a
......@@ -16,7 +16,7 @@ vue2 + vue-rotuer2 + vuex2 + webpack + ES6/7 + fetch + sass + flex + svg + http-
- [x] 定位功能 -- 完成
- [x] 选择城市 -- 完成
- [x] 搜索地址 -- 完成
- [ ] 展示所选地址附近商家列表
- [x] 展示所选地址附近商家列表
- [ ] 搜索美食,餐馆
- [ ] 根据距离、销量、评分、特色菜等进行排序和筛选
- [ ] 单个餐馆的详细信息展示,商品列表,优惠活动
......
......@@ -32,6 +32,11 @@
<path class="path1" d="M16 26.382l-8.16 4.992c-1.5 0.918-2.382 0.264-1.975-1.435l2.226-9.303-7.269-6.218c-1.337-1.143-0.987-2.184 0.755-2.322l9.536-0.758 3.667-8.835c0.674-1.624 1.772-1.613 2.442 0l3.667 8.835 9.536 0.758c1.753 0.139 2.082 1.187 0.755 2.322l-7.269 6.218 2.226 9.303c0.409 1.71-0.485 2.347-1.975 1.435l-8.16-4.992z">
</path>
</symbol>
<symbol viewBox="0 0 32 32" id="backtop">
<path fill="#999" d="M16 31.767c8.708 0 15.767-7.059 15.767-15.767S24.708.233 16 .233C7.292.233.233 7.292.233 16S7.292 31.767 16 31.767zm0-.261C7.436 31.506.494 24.564.494 16S7.436.494 16 .494 31.506 7.436 31.506 16 24.564 31.506 16 31.506z"></path>
<path fill="#999" d="M15.739 18.893c0 .56.782.56.782 0v-8.878c0-.56-.782-.56-.782 0v8.878z"></path>
<path fill="#999" d="M11.331 14.646l4.703-4.503c.091-.095.258-.282.249-.272-.017.018-.046.04-.165.04s-.148-.021-.165-.04c-.009-.01.157.177.236.259l4.769 4.517.538-.568-4.755-4.503a17.801 17.801 0 0 1-.215-.238c-.132-.143-.225-.21-.408-.21s-.275.068-.408.21c0 0-.161.181-.229.252l-4.691 4.49.541.565zM11.118 8.838h10.001v-.782H11.118v.782zM13.184 21.797v.364h1.101a5.835 5.835 0 0 1-.068.545h-.883v2.473h.364v-2.125h1.574v2.114h.369v-2.462h-1.044c.031-.177.052-.358.068-.545h1.148v-.364h-2.629zm1.725 3.403l-.255.239c.395.322.701.623.93.904l.27-.275a6.815 6.815 0 0 0-.945-.868zm-.629-1.839v.925c-.016.442-.125.8-.332 1.075-.218.265-.603.478-1.158.639l.203.317c.577-.177.992-.416 1.247-.717.26-.322.395-.764.41-1.314v-.925h-.369zm-2.348 2.909c.296 0 .447-.156.447-.462v-3.647h.623v-.364h-1.808v.364h.8v3.553c0 .145-.068.223-.192.223-.171 0-.353-.01-.54-.021l.083.353h.587zm5.149-3.636l-.343.125c.13.229.239.478.332.748h-.701v.364h2.603v-.364h-.629c.135-.234.255-.499.364-.795l-.348-.119a5.784 5.784 0 0 1-.384.914h-.545a5.06 5.06 0 0 0-.348-.873zm2.129-.842v4.535h.364v-4.192h.93a14.672 14.672 0 0 1-.509 1.46c.405.499.613.899.618 1.205-.005.187-.031.312-.083.379-.052.062-.171.099-.358.109-.099 0-.218-.01-.364-.021l.119.395c.426 0 .712-.068.857-.192.135-.125.203-.348.203-.67-.005-.312-.203-.717-.592-1.205.187-.468.358-.977.519-1.522v-.281H19.21zm-2.742.286v.364h2.468v-.364h-1.06a8.404 8.404 0 0 0-.171-.535l-.384.068c.068.14.13.296.192.468h-1.044zm2.264 2.265h-2.068v1.958h.369v-.291h1.33v.291h.369v-1.958zm-1.698 1.314v-.961h1.33v.961h-1.33z"></path>
</symbol>
</defs>
</svg>
<router-view></router-view>
......
<template>
<ul>
<router-link :to="{path: 'food', query:{}}" v-for="item in shopListArr" tag='li' :key="item.id" class="shop_li">
<section>
<img :src="imgBaseUrl + subImgUrl(item.image_path)" class="shop_img">
</section>
<hgroup class="shop_right">
<header class="shop_detail_header">
<h4 :class="item.is_premium? 'premium': ''" class="" class="shop_title ellipsis">{{item.name}}</h4>
<ul class="shop_detail_ul">
<li v-for="item in item.supports" key="item.id" class="supports">{{item.icon_name}}</li>
</ul>
</header>
<h5></h5>
<h5></h5>
</hgroup>
</router-link>
</ul>
<div>
<a id="top"></a>
<ul v-load-more="loaderMore" >
<router-link :to="{path: 'food', query:{}}" v-for="item in shopListArr" tag='li' :key="item.id" class="shop_li">
<section>
<img :src="imgBaseUrl + subImgUrl(item.image_path)" class="shop_img">
</section>
<hgroup class="shop_right">
<header class="shop_detail_header">
<h4 :class="item.is_premium? 'premium': ''" class="" class="shop_title ellipsis">{{item.name}}</h4>
<ul class="shop_detail_ul">
<li v-for="item in item.supports" key="item.id" class="supports">{{item.icon_name}}</li>
</ul>
</header>
<h5 class="rating_order_num">
<section class="rating_order_num_left">
<section class="rating_section">
<div class="rating_container">
<span class="star_container">
<svg class="grey_fill" v-for="num in 5" key="num">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#star"></use>
</svg>
</span>
<div :style="'width:' + item.rating*2/5 + 'rem'" class="star_overflow">
<span class="star_container" >
<svg class="orange_fill" v-for="num in 5" key="num">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#star"></use>
</svg>
</span>
</div>
</div>
<span class="rating_num">{{item.rating}}</span>
</section>
<section class="order_section">
月售{{item.recent_order_num}}
</section>
</section>
<section class="rating_order_num_right" v-if="item.delivery_mode">
<span class="delivery_style delivery_left">{{item.delivery_mode.text}}</span>
<span class="delivery_style delivery_right">准时达</span>
</section>
</h5>
<h5 class="fee_distance">
<section class="fee">
¥{{item.float_minimum_order_amount}}起送
<span class="segmentation">/</span>
{{item.piecewise_agent_fee.tips}}
</section>
<section class="distance_time">
<span>{{item.distance > 1000? (item.distance/1000).toFixed(2) + 'km': item.distance + 'm'}}
<span class="segmentation">/</span>
</span>
<span class="order_time">{{item.order_lead_time}}分钟</span>
</section>
</h5>
</hgroup>
</router-link>
</ul>
<a class="return_top" @click="backTop" v-if="showBack">
<svg class="back_top_svg">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#backtop"></use>
</svg>
</a>
<footer class="loader_more" v-show="preventRepeatReuqest">正在加载更多商家...</footer>
</div>
</template>
<script>
......@@ -23,16 +71,24 @@
import {mapState} from 'vuex'
import {imgBaseUrl} from '../../config/env'
import {msiteShopList} from '../../service/getData'
import * as Tool from '../../config/mUtils'
export default {
data(){
return {
offset: 0, // 批次加载店铺列表,每次加载20个 limit = 20
shopListArr:[], // 店铺列表数据
imgBaseUrl,
imgBaseUrl, //图片域名地址
preventRepeatReuqest: false, //到达底部加载数据,防止重复加载
showBack: false, //显示返回顶部按钮
}
},
async mounted(){
//获取数据
this.shopListArr = await msiteShopList(this.latitude, this.longitude, this.offset);
Tool.showBack(status => {
this.showBack = status;
})
},
props: [],
components: {
......@@ -44,6 +100,7 @@ export default {
])
},
methods: {
//传递过来的图片地址需要处理后才能正常使用
subImgUrl(path){
let suffix;
if (path.indexOf('jpeg') !== -1) {
......@@ -53,12 +110,29 @@ export default {
}
let url = '/' + path.substr(0,1) + '/' + path.substr(1,2) + '/' + path.substr(3) + suffix;
return url
}
},
watch: {
},
//到达底部加载更多数据
async loaderMore(){
//防止重复请求
if (this.preventRepeatReuqest) {
return
}
this.preventRepeatReuqest = true;
this.offset += 20;
let res = await msiteShopList(this.latitude, this.longitude, this.offset);
this.shopListArr = this.shopListArr.concat(res);
//当获取数据小于20,说明没有更多数据,不需要再次请求数据
if (res.length < 20) {
return
}
this.preventRepeatReuqest = false;
},
//返回顶部
backTop(){
window.scrollTo(0,0);
}
}
}
</script>
......@@ -67,12 +141,12 @@ export default {
.shop_li{
display: flex;
border-bottom: 0.025rem solid #f1f1f1;
padding: 0.8rem 0.4rem;
padding: 0.7rem 0.4rem;
}
.shop_img{
@include wh(2.7rem, 2.7rem);
display: block;
margin-right: 0.3rem;
margin-right: 0.4rem;
}
.shop_right{
flex: auto;
......@@ -80,12 +154,20 @@ export default {
@include fj;
align-items: center;
.shop_title{
@include sc(0.7rem, #333);
font-weight: 700;
width: 8.5rem;
color: #333;
@include font(0.65rem, 0.65rem, 'PingFangSC-Regular');
font-weight: 700;
}
.premium{
.premium::before{
content: '品牌';
display: inline-block;
font-size: 0.5rem;
background-color: #ffd930;
padding: 0 0.1rem;
border-radius: 0.1rem;
margin-right: 0.2rem;
vertical-align: top;
}
.shop_detail_ul{
display: flex;
......@@ -94,9 +176,93 @@ export default {
border: 0.025rem solid #f1f1f1;
padding: 0.04rem;
border-radius: 0.08rem;
margin-left: 0.1rem;
margin-left: 0.05rem;
}
}
}
.rating_order_num{
@include fj(space-between);
height: 0.6rem;
margin-top: 0.52rem;
.rating_order_num_left{
@include fj(flex-start);
.rating_section{
display: flex;
.rating_container{
position: relative;
width: 2rem;
.star_overflow{
overflow: hidden;
position: relative;
height: 100%;
}
.star_container{
position: absolute;
display: flex;
width: 2rem;
height: 0.4rem;
top: -0.02rem;
.grey_fill{
fill: #d1d1d1;
}
.orange_fill{
fill: #ff9a0d;
}
}
}
.rating_num{
@include sc(0.4rem, #ff6000);
margin: 0 0.2rem;
}
}
.order_section{
@include sc(0.4rem, #666);
}
}
.rating_order_num_right{
display: flex;
.delivery_style{
font-size: 0.4rem;
padding: 0.04rem 0.08rem 0;
border-radius: 0.08rem;
margin-left: 0.08rem;
}
.delivery_left{
color: #fff;
background-color: $blue;
border: 0.025rem solid $blue;
}
.delivery_right{
color: $blue;
border: 0.025rem solid $blue;
}
}
}
.fee_distance{
margin-top: 0.52rem;
@include fj;
@include sc(0.5rem, #666);
.distance_time{
.order_time{
color: $blue;
}
}
.segmentation{
color: #ccc;
}
}
}
.loader_more{
@include font(0.6rem, 3);
text-align: center;
color: #999;
}
.return_top{
position: fixed;
bottom: 3rem;
right: 1rem;
.back_top_svg{
@include wh(2rem, 2rem);
}
}
......
......@@ -4,7 +4,7 @@
const setStore = (name, content) => {
if (!name) return;
if (typeof content !== 'string') {
content = JSON.stringify(content)
content = JSON.stringify(content);
}
window.localStorage.setItem(name, content);
}
......@@ -25,6 +25,107 @@ const removeStore = name => {
window.localStorage.removeItem(name);
}
/**
* 获取style样式
*/
const getStyle = (obj,attr) => {
if(obj.currentStyle){
return obj.currentStyle[attr];
}
else{
return document.defaultView.getComputedStyle(obj,null)[attr];
}
}
/**
* 页面到达底部,加载更多
*/
const loadMore = (el, callback) => {
let windowHeight = window.screen.height;
let height;
let setTop;
let paddingBottom;
let marginBottom;
let requestFram;
let oldScrollTop;
el.addEventListener('touchstart',() => {
height = el.offsetHeight;
setTop = el.offsetTop;
paddingBottom = parseInt(getStyle(el,'paddingBottom'));
marginBottom = parseInt(getStyle(el,'marginBottom'));
},false)
el.addEventListener('touchmove',() => {
loadMore();
},false)
el.addEventListener('touchend',() => {
oldScrollTop = document.body.scrollTop;
moveEnd();
},false)
const moveEnd = () => {
requestFram = requestAnimationFrame(() => {
if (document.body.scrollTop != oldScrollTop) {
oldScrollTop = document.body.scrollTop;
moveEnd();
}else{
cancelAnimationFrame(requestFram);
//为了防止鼠标抬起时已经渲染好数据从而导致重获取数据,应该重新获取dom高度
height = el.offsetHeight;
loadMore();
}
})
}
const loadMore = () => {
if (document.body.scrollTop + windowHeight >= height + setTop + paddingBottom + marginBottom) {
callback();
}
}
}
/**
* 显示返回顶部按钮
*/
const showBack = callback => {
let requestFram;
let oldScrollTop;
document.addEventListener('touchstart',() => {
showBackFun();
},false)
document.addEventListener('touchmove',() => {
showBackFun();
},false)
document.addEventListener('touchend',() => {
oldScrollTop = document.body.scrollTop;
moveEnd();
},false)
const moveEnd = () => {
requestFram = requestAnimationFrame(() => {
if (document.body.scrollTop != oldScrollTop) {
oldScrollTop = document.body.scrollTop;
showBackFun();
moveEnd();
}else{
cancelAnimationFrame(requestFram);
}
})
}
const showBackFun = () => {
if (document.body.scrollTop > 500) {
callback(true);
}else{
callback(false);
}
}
}
export {setStore, getStore, removeStore}
\ No newline at end of file
export {setStore, getStore, removeStore, getStyle, loadMore, showBack}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import store from './store/'
import {routerMode} from './config/env'
import './style/common.scss'
import './config/rem'
import * as Tool from './config/mUtils'
Vue.use(VueRouter)
const router = new VueRouter({
......@@ -13,6 +14,53 @@ const router = new VueRouter({
strict: process.env.NODE_ENV !== 'production'
})
Vue.directive('load-more',{
bind: (el, binding) => {
let windowHeight = window.screen.height;
let height;
let setTop;
let paddingBottom;
let marginBottom;
let requestFram;
let oldScrollTop;
el.addEventListener('touchstart',() => {
height = el.offsetHeight;
setTop = el.offsetTop;
paddingBottom = parseInt(Tool.getStyle(el,'paddingBottom'));
marginBottom = parseInt(Tool.getStyle(el,'marginBottom'));
},false)
el.addEventListener('touchmove',() => {
loadMore();
},false)
el.addEventListener('touchend',() => {
oldScrollTop = document.body.scrollTop;
moveEnd()
},false)
const moveEnd = () => {
requestFram = requestAnimationFrame(() => {
if (document.body.scrollTop != oldScrollTop) {
oldScrollTop = document.body.scrollTop;
moveEnd()
}else{
cancelAnimationFrame(requestFram);
height = el.offsetHeight;
loadMore();
}
})
}
const loadMore = () => {
if (document.body.scrollTop + windowHeight >= height + setTop + paddingBottom + marginBottom) {
binding.value();
}
}
}
})
new Vue({
router,
store,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册