npm install -g @vue/cli //安装vue脚手架,如果之前安装过就不再需要安装
vue init webpack gshop
cd gshop
npm install
npm run dev
\1) 编码测试
npm run dev
访问: http://localhost:8080
编码, 自动编译打包(HMR), 查看效果
\2) 打包发布
npm run build
npm install -g serve
serve dist
访问: http://localhost:5000
2.5.2. 安装 stylus 依赖包
npm install [email protected] --save
npm install [email protected] --save-dev
APP
<script>
import FooterGuide from './components/FooterGuide/FooterGuide.vue';
export default {
components: { FooterGuide }
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
#app
width 100%
height 100%
background #f5f5f5
</style>
FooterGuide/FooterGuide.vue
外卖
搜索
订单
我的
<script>
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.footer_guide
top-border-1px(#e4e4e4)
position fixed
z-index 100
left 0
right 0
bottom 0
background-color #fff
width 100%
height 50px
display flex
.guide_item
display flex
flex 1
text-align center
flex-direction column
align-items centermargin 5px
color #999999
&.on
color #02a774
span
font-size 12px
margin-top 2px
margin-bottom 2px
.iconfont
font-size 22px
</style>
FooterGuide
外卖
搜索
订单
我的
<script>
export default {
methods: {
goto(path){
this.$router.replace(path)
},
isCurrent(path){
return this.$route.path===path
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.footer_guide
top-border-1px(#e4e4e4)
position fixed
z-index 100
left 0
right 0
bottom 0
background-color #fff
width 100%
height 50px
display flex
.guide_item
display flex
flex 1
text-align center
flex-direction column
align-items centermargin 5px
color #999999
&.on
color #02a774
span
font-size 12px
margin-top 2px
margin-bottom 2px
.iconfont
font-size 22px
</style>
msite.vue
昌平区北七家宏福科技园(337省道北)
登录|注册
甜品饮品
商超便利
美食
简餐
新店特惠
准时达
预订早餐
土豪推荐
甜品饮品
商超便利
美食
简餐
新店特惠
准时达
预订早餐
土豪推荐
<script>
export default {
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.msite
width 100%
.header
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.icon-sousuo
font-size 25px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 50%
color #fff
text-align center
.header_title_text
font-size 20px
color #fff
display block
.header_login
font-size 14px
color #fff
position absolute
right 15px
top 50%
transform translateY(-50%)
.header_login_text
color #fff
.msite_nav
bottom-border-1px(#e4e4e4)
margin-top 45px
height 200px
background #fff
.swiper-container
width 100%
height 100%
.swiper-wrapper
width 100%
height 100%
.swiper-slide
display flex
justify-content center
align-items flex-start
flex-wrap wrap
.link_to_food
width 25%
.food_container
display block
width 100%
text-align centerpadding-bottom 10px
font-size 0
img
display inline-block
width 50px
height 50px
span
display block
width 100%
text-align center
font-size 13px
color #666
.swiper-pagination
>span.swiper-pagination-bullet-active
background #02a774
.msite_shop_list
top-border-1px(#e4e4e4)
margin-top 10px
background #fff
.shop_header
padding 10px 10px 0 10px
.shop_icon
margin-left 5px
color #999
.shop_header_title
color #999
font-size 14px
line-height 20px
.shop_container
margin-bottom 50px
.shop_list
.shop_li
bottom-border-1px(#f1f1f1)
width 100%
>a
clearFix()
display block
box-sizing border-box
padding 15px 8px
width 100%
.shop_left
float left
box-sizing border-box
width 23%
height 75px
padding-right 10px
.shop_img
display block
width 100%
height 100%
.shop_right
float right
width 77%
.shop_detail_header
clearFix()
width 100%
.shop_title
text_ellipsis()
float left
width 200px
color #333
font-size 16px
line-height 16px
font-weight 700
&::before
content '品牌'
display inline-block
font-size 11px
line-height 11px
color #333
background-color #ffd930
padding 2px 2px
border-radius 2px
margin-right 5px
.shop_detail_ul
float right
margin-top 3px
.supports
float left
font-size 10px
color #999
border 1px solid #f1f1f1
padding 0 2px
border-radius 2px
.shop_rating_order
clearFix()
width 100%
margin-top 18px
margin-bottom 8px
.shop_rating_order_left
float left
color #ff9a0d
.star //2x 图 3x 图
float left
font-size 0
.star-item
display inline-block
background-repeat no-repeat
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right: 0
&.on
bg-image('./images/stars/star48_on')
&.half
bg-image('./images/stars/star48_half')
&.off
bg-image('./images/stars/star48_off')
&.star-36
.star-item
width 15px
height 15px
margin-right 6px
background-size 15px 15px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star36_on')
&.half
bg-image('./images/stars/star36_half')
&.off
bg-image('./images/stars/star36_off')
&.star-24
.star-item
width 10px
height 10px
margin-right 3px
background-size 10px 10px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star24_on')
&.half
bg-image('./images/stars/star24_half')
&.off
bg-image('./images/stars/star24_off')
.rating_section
float left
font-size 10px
color #ff6000
margin-left 4px
.order_section
float left
font-size 10px
color #666
transform scale(.8)
.shop_rating_order_right
float right
font-size 0
.delivery_style
transform-origin 35px 0
transform scale(.7)
display inline-block
font-size 12px
padding 1px
border-radius 2px
.delivery_left
color #fff
margin-right -10px
background-color #02a774
border 1px solid #02a774
.delivery_right
color #02a774
border 1px solid #02a774
.shop_distance
clearFix()
width 100%
font-size 12px
.shop_delivery_msg
float left
transform-origin 0
transform scale(.9)
width: 200px
color #666
.segmentation
color #ccc
</style>
search.vue
<script>
export default {}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.search //搜索
width 100%
height 100%
.header //头部公共 css
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.iconfont
font-size 22px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 30%
color #fff
font-size 22px
text-align center
.search_form
clearFix()
margin-top 45px
background-color #fff
padding 12px 8px
input
height 35px
padding 0 4px
border-radius 2px
font-weight bold
outline none
&.search_input
float left
width 79%
border 4px solid #f2f2f2
font-size 14px
color #333
background-color #f2f2f2
&.search_submit
float right
width 18%
border 4px solid #02a774
font-size 16px
color #fff
background-color #02a774
</style>
#### Order.vue
订单列表
立即登陆
<script>
export default {}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.order //订单
.header
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.icon-sousuo
font-size 25px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 50%
color #fff
text-align center
.header_title_text
font-size 20px
color #fff
display block
.header_login
font-size 14px
color #fff
position absolute
right 15px
top 50%
transform translateY(-50%)
.header_login_text
color #fff
width 100%
.order_no_login
padding-top 140px
width 60%
margin 0 auto
text-align center
>img
display block
width 100%
height 30%
>h3
padding 10px 0
font-size 17px
color #6a6a6a
>button
display inline-block
background #02a774
font-size 14px
color #fff
border 0
outline none
border-radius 5px
padding 10px 20px
</style>
#### Profile.vue
我的
0.00 元
我的余额
0 个
我的优惠
0 分
我的积分
<script>
export default {}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.profile //我的
width 100%
.header //头部公共 css
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.iconfont
font-size 22px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 30%
color #fff
font-size 22px
text-align center
.profile-number
margin-top 45.5px
.profile-link
clearFix()
position relative
display block
background #02a774
padding 20px 10px
.profile_image
float left
width 60px
height 60px
border-radius 50%
overflow hidden
vertical-align top
.icon-person
background #e4e4e4
font-size 62px
.user-info
float left
margin-top 8px
margin-left 15px
p
font-weight: 700
font-size 18px
color #fff
&.user-info-top
padding-bottom 8px
.user-icon
display inline-block
margin-left -15px
margin-right 5px
width 20px
height 20px
.icon-mobile
font-size 30px
vertical-align text-top
.icon-mobile-number
font-size 14px
color #fff
.arrow
width 12px
height 12px
position absolute
right 15px
top 40%
.icon-jiantou1
color #fff
font-size 5px
.profile_info_data
bottom-border-1px(#e4e4e4)
width 100%
background #fff
overflow hidden
.info_data_list
clearFix()
.info_data_link
float left
width 33%
text-align center
border-right 1px solid #f1f1f1
.info_data_top
display block
width 100%
font-size 14px
color #333
padding 15px 5px 10px
span
display inline-block
font-size 30px
color #f90
font-weight 700
line-height 30px
.info_data_bottom
display inline-block
font-size 14px
color #666
font-weight 400
padding-bottom 10px
.info_data_link:nth-of-type(2)
.info_data_top
span
color #ff5f3e
.info_data_link:nth-of-type(3)
border 0
.info_data_top
span
color #6ac20b
.profile_my_order
top-border-1px(#e4e4e4)
margin-top 10px
background #fff
.my_order
display flex
align-items center
padding-left 15px
>span
display flex
align-items center
width 20px
height 20px
>.iconfont
margin-left -10px
font-size 30px
.icon-order-s
color #02a774
.icon-jifen
color #ff5f3e
.icon-vip
color #f90
.icon-fuwu
color #02a774
.my_order_div
width 100%
border-bottom 1px solid #f1f1f1
padding 18px 10px 18px 0
font-size 16px
color #333
display flex
justify-content space-between
span
display inline-block
.my_order_icon
float right
width 10px
height 10px
.icon-jiantou1
color #bbb
font-size 10px
</style>
#### **components/HeaderTop/HeaderTop.vue**
{{title}}
<script>
export default {
props: {
title: String
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.header
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.icon-sousuo
font-size 25px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 50%
color #fff
text-align center
.header_title_text
font-size 20px
color #fff
display block
.header_login
font-size 14px
color #fff
position absolute
right 15px
top 50%
transform translateY(-50%)
.header_login_text
color #fff
</style>
#### Msite.vue
登录|注册
甜品饮品
商超便利
美食
简餐
新店特惠
准时达
预订早餐
土豪推荐
甜品饮品
商超便利
美食
简餐
新店特惠
准时达
预订早餐
土豪推荐
<script>
import Swiper from 'swiper'
import 'swiper/swiper.min.css'
export default {
mounted() {
/* eslint-disable no-new */
new Swiper('.swiper-container', {
pagination: {
el: '.swiper-pagination'
},
loop: true
})
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.msite
width 100%
.header
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.icon-sousuo
font-size 25px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 50%
color #fff
text-align center
.header_title_text
font-size 20px
color #fff
display block
.header_login
font-size 14px
color #fff
position absolute
right 15px
top 50%
transform translateY(-50%)
.header_login_text
color #fff
.msite_nav
bottom-border-1px(#e4e4e4)
margin-top 45px
height 200px
background #fff
.swiper-container
width 100%
height 100%
.swiper-wrapper
width 100%
height 100%
.swiper-slide
display flex
justify-content center
align-items flex-start
flex-wrap wrap
.link_to_food
width 25%
.food_container
display block
width 100%
text-align centerpadding-bottom 10px
font-size 0
img
display inline-block
width 50px
height 50px
span
display block
width 100%
text-align center
font-size 13px
color #666
.swiper-pagination
>span.swiper-pagination-bullet-active
background #02a774
.msite_shop_list
top-border-1px(#e4e4e4)
margin-top 10px
background #fff
.shop_header
padding 10px 10px 0 10px
.shop_icon
margin-left 5px
color #999
.shop_header_title
color #999
font-size 14px
line-height 20px
.shop_container
margin-bottom 50px
.shop_list
.shop_li
bottom-border-1px(#f1f1f1)
width 100%
>a
clearFix()
display block
box-sizing border-box
padding 15px 8px
width 100%
.shop_left
float left
box-sizing border-box
width 23%
height 75px
padding-right 10px
.shop_img
display block
width 100%
height 100%
.shop_right
float right
width 77%
.shop_detail_header
clearFix()
width 100%
.shop_title
text_ellipsis()
float left
width 200px
color #333
font-size 16px
line-height 16px
font-weight 700
&::before
content '品牌'
display inline-block
font-size 11px
line-height 11px
color #333
background-color #ffd930
padding 2px 2px
border-radius 2px
margin-right 5px
.shop_detail_ul
float right
margin-top 3px
.supports
float left
font-size 10px
color #999
border 1px solid #f1f1f1
padding 0 2px
border-radius 2px
.shop_rating_order
clearFix()
width 100%
margin-top 18px
margin-bottom 8px
.shop_rating_order_left
float left
color #ff9a0d
.star //2x 图 3x 图
float left
font-size 0
.star-item
display inline-block
background-repeat no-repeat
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right: 0
&.on
bg-image('./images/stars/star48_on')
&.half
bg-image('./images/stars/star48_half')
&.off
bg-image('./images/stars/star48_off')
&.star-36
.star-item
width 15px
height 15px
margin-right 6px
background-size 15px 15px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star36_on')
&.half
bg-image('./images/stars/star36_half')
&.off
bg-image('./images/stars/star36_off')
&.star-24
.star-item
width 10px
height 10px
margin-right 3px
background-size 10px 10px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star24_on')
&.half
bg-image('./images/stars/star24_half')
&.off
bg-image('./images/stars/star24_off')
.rating_section
float left
font-size 10px
color #ff6000
margin-left 4px
.order_section
float left
font-size 10px
color #666
transform scale(.8)
.shop_rating_order_right
float right
font-size 0
.delivery_style
transform-origin 35px 0
transform scale(.7)
display inline-block
font-size 12px
padding 1px
border-radius 2px
.delivery_left
color #fff
margin-right -10px
background-color #02a774
border 1px solid #02a774
.delivery_right
color #02a774
border 1px solid #02a774
.shop_distance
clearFix()
width 100%
font-size 12px
.shop_delivery_msg
float left
transform-origin 0
transform scale(.9)
width: 200px
color #666
.segmentation
color #ccc
</style>
components/ShopList/ShopList.vue
<template>
<div class="shop_container">
<ul class="shop_list">
<li class="shop_li border-1px">
<a>
<div class="shop_left">
<img class="shop_img" src="./images/shop/1.jpg">
</div>
<div class="shop_right">
<section class="shop_detail_header">
<h4 class="shop_title" >锄禾日当午,汗滴禾下土</h4>
<ul class="shop_detail_ul">
<li class="supports">保</li>
<li class="supports">准</li>
<li class="supports">票</li>
</ul>
</section>
<section class="shop_rating_order">
<section class="shop_rating_order_left">
<div class="star star-24">
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item half"></span>
<span class="star-item off"></span>
</div>
<div class="rating_section">
3.6
</div>
<div class="order_section">
月售 106 单
</div>
</section>
<section class="shop_rating_order_right">
<span class="delivery_style delivery_left">硅谷专送</span>
<span class="delivery_style delivery_right">准时达</span>
</section>
</section>
<section class="shop_distance">
<p class="shop_delivery_msg">
<span>¥20 起送</span>
<span class="segmentation">/</span>
<span>配送费约¥5</span>
</p>
</section>
</div>
</a>
</li>
<li class="shop_li border-1px">
<a>
<div class="shop_left">
<img class="shop_img" src="./images/shop/2.jpg">
</div>
<div class="shop_right">
<section class="shop_detail_header">
<h4 class="shop_title ellipsis" >锄禾日当午,汗滴禾下土</h4>
<ul class="shop_detail_ul">
<li class="supports">保</li>
<li class="supports">准</li>
<li class="supports">票</li>
</ul>
</section>
<section class="shop_rating_order">
<section class="shop_rating_order_left">
<div class="star star-24">
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item off"></span>
</div>
<div class="rating_section">
4.1
</div>
<div class="order_section">
月售 106 单
</div>
</section>
<section class="shop_rating_order_right">
<span class="delivery_style delivery_left">硅谷专送</span>
<span class="delivery_style delivery_right">准时达</span>
</section>
</section>
<section class="shop_distance">
<p class="shop_delivery_msg">
<span>¥20 起送</span>
<span class="segmentation">/</span>
<span>配送费约¥5</span>
</p>
</section>
</div>
</a>
</li>
<li class="shop_li border-1px">
<a>
<div class="shop_left">
<img class="shop_img" src="./images/shop/3.jpg">
</div>
<div class="shop_right">
<section class="shop_detail_header">
<h4 class="shop_title ellipsis" >锄禾日当午,汗滴禾下土</h4>
<ul class="shop_detail_ul">
<li class="supports">保</li>
<li class="supports">准</li>
<li class="supports">票</li>
</ul>
</section>
<section class="shop_rating_order">
<section class="shop_rating_order_left">
<div class="star star-24">
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item off"></span>
<span class="star-item off"></span>
</div>
<div class="rating_section">
3.2
</div>
<div class="order_section">
月售 106 单
</div>
</section>
<section class="shop_rating_order_right">
<span class="delivery_style delivery_left">硅谷专送</span>
<span class="delivery_style delivery_right">准时达</span>
</section>
</section>
<section class="shop_distance">
<p class="shop_delivery_msg">
<span>¥20 起送</span>
<span class="segmentation">/</span>
<span>配送费约¥5</span>
</p>
</section>
</div>
</a>
</li>
<li class="shop_li border-1px">
<a>
<div class="shop_left">
<img class="shop_img" src="./images/shop/4.jpg">
</div>
<div class="shop_right">
<section class="shop_detail_header">
<h4 class="shop_title ellipsis" >锄禾日当午,汗滴禾下土</h4>
<ul class="shop_detail_ul">
<li class="supports">保</li>
<li class="supports">准</li>
<li class="supports">票</li>
</ul>
</section>
<section class="shop_rating_order">
<section class="shop_rating_order_left">
<div class="star star-24">
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item on"></span>
<span class="star-item half"></span>
<span class="star-item off"></span>
</div>
<div class="rating_section">
3.6
</div>
<div class="order_section">
月售 106 单
</div>
</section>
<section class="shop_rating_order_right">
<span class="delivery_style delivery_left">硅谷专送</span>
<span class="delivery_style delivery_right">准时达</span>
</section>
</section>
<section class="shop_distance">
<p class="shop_delivery_msg">
<span>¥20 起送</span>
<span class="segmentation">/</span>
<span>配送费约¥5</span>
</p>
</section>
</div>
</a>
</li>
</ul>
</div>
</template>
<script>
export default {
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.shop_container
margin-bottom 50px
.shop_list
.shop_li
bottom-border-1px(#f1f1f1)
width 100%
>a
clearFix()
display block
box-sizing border-box
padding 15px 8px
width 100%
.shop_left
float left
box-sizing border-box
width 23%
height 75px
padding-right 10px
.shop_img
display block
width 100%
height 100%
.shop_right
float right
width 77%
.shop_detail_header
clearFix()
width 100%
.shop_title
text_ellipsis()
float left
width 200px
color #333
font-size 16px
line-height 16px
font-weight 700
&::before
content '品牌'
display inline-block
font-size 11px
line-height 11px
color #333
background-color #ffd930
padding 2px 2px
border-radius 2px
margin-right 5px
.shop_detail_ul
float right
margin-top 3px
.supports
float left
font-size 10px
color #999
border 1px solid #f1f1f1
padding 0 2px
border-radius 2px
.shop_rating_order
clearFix()
width 100%
margin-top 18px
margin-bottom 8px
.shop_rating_order_left
float left
color #ff9a0d
.star //2x 图 3x 图
float left
font-size 0
.star-item
display inline-block
background-repeat no-repeat
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right: 0
&.on
bg-image('./images/stars/star48_on')
&.half
bg-image('./images/stars/star48_half')
&.off
bg-image('./images/stars/star48_off')
&.star-36
.star-item
width 15px
height 15px
margin-right 6px
background-size 15px 15px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star36_on')
&.half
bg-image('./images/stars/star36_half')
&.off
bg-image('./images/stars/star36_off')
&.star-24
.star-item
width 10px
height 10px
margin-right 3px
background-size 10px 10px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star24_on')
&.half
bg-image('./images/stars/star24_half')
&.off
bg-image('./images/stars/star24_off')
.rating_section
float left
font-size 10px
color #ff6000
margin-left 4px
.order_section
float left
font-size 10px
color #666
transform scale(.8)
.shop_rating_order_right
float right
font-size 0
.delivery_style
transform-origin 35px 0
transform scale(.7)
display inline-block
font-size 12px
padding 1px
border-radius 2px
.delivery_left
color #fff
margin-right -10px
background-color #02a774
border 1px solid #02a774
.delivery_right
color #02a774
border 1px solid #02a774
.shop_distance
clearFix()
width 100%
font-size 12px
.shop_delivery_msg
float left
transform-origin 0
transform scale(.9)
width: 200px
color #666
.segmentation
color #ccc
</style>
</style>
登录|注册
甜品饮品
商超便利
美食
简餐
新店特惠
准时达
预订早餐
土豪推荐
甜品饮品
商超便利
美食
简餐
新店特惠
准时达
预订早餐
土豪推荐
<script>
import ShopList from '../../components/ShopList/ShopList.vue'
import HeaderTop from '../../components/HeaderTop/HeaderTop.vue'
export default {
components: {
HeaderTop,
ShopList,
}
}
</script>
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.msite
width 100%
.header
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.icon-sousuo
font-size 25px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 50%
color #fff
text-align center
.header_title_text
font-size 20px
color #fff
display block
.header_login
font-size 14px
color #fff
position absolute
right 15px
top 50%
transform translateY(-50%)
.header_login_text
color #fff
.msite_nav
bottom-border-1px(#e4e4e4)
margin-top 45px
height 200px
background #fff
.swiper-container
width 100%
height 100%
.swiper-wrapper
width 100%
height 100%
.swiper-slide
display flex
justify-content center
align-items flex-start
flex-wrap wrap
.link_to_food
width 25%
.food_container
display block
width 100%
text-align centerpadding-bottom 10px
font-size 0
img
display inline-block
width 50px
height 50px
span
display block
width 100%
text-align center
font-size 13px
color #666
.swiper-pagination
>span.swiper-pagination-bullet-active
background #02a774
.msite_shop_list
top-border-1px(#e4e4e4)
margin-top 10px
background #fff
.shop_header
padding 10px 10px 0 10px
.shop_icon
margin-left 5px
color #999
.shop_header_title
color #999
font-size 14px
line-height 20px
.shop_container
margin-bottom 50px
.shop_list
.shop_li
bottom-border-1px(#f1f1f1)
width 100%
>a
clearFix()
display block
box-sizing border-box
padding 15px 8px
width 100%
.shop_left
float left
box-sizing border-box
width 23%
height 75px
padding-right 10px
.shop_img
display block
width 100%
height 100%
.shop_right
float right
width 77%
.shop_detail_header
clearFix()
width 100%
.shop_title
text_ellipsis()
float left
width 200px
color #333
font-size 16px
line-height 16px
font-weight 700
&::before
content '品牌'
display inline-block
font-size 11px
line-height 11px
color #333
background-color #ffd930
padding 2px 2px
border-radius 2px
margin-right 5px
.shop_detail_ul
float right
margin-top 3px
.supports
float left
font-size 10px
color #999
border 1px solid #f1f1f1
padding 0 2px
border-radius 2px
.shop_rating_order
clearFix()
width 100%
margin-top 18px
margin-bottom 8px
.shop_rating_order_left
float left
color #ff9a0d
.star //2x 图 3x 图
float left
font-size 0
.star-item
display inline-block
background-repeat no-repeat
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right: 0
&.on
bg-image('./images/stars/star48_on')
&.half
bg-image('./images/stars/star48_half')
&.off
bg-image('./images/stars/star48_off')
&.star-36
.star-item
width 15px
height 15px
margin-right 6px
background-size 15px 15px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star36_on')
&.half
bg-image('./images/stars/star36_half')
&.off
bg-image('./images/stars/star36_off')
&.star-24
.star-item
width 10px
height 10px
margin-right 3px
background-size 10px 10px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star24_on')
&.half
bg-image('./images/stars/star24_half')
&.off
bg-image('./images/stars/star24_off')
.rating_section
float left
font-size 10px
color #ff6000
margin-left 4px
.order_section
float left
font-size 10px
color #666
transform scale(.8)
.shop_rating_order_right
float right
font-size 0
.delivery_style
transform-origin 35px 0
transform scale(.7)
display inline-block
font-size 12px
padding 1px
border-radius 2px
.delivery_left
color #fff
margin-right -10px
background-color #02a774
border 1px solid #02a774
.delivery_right
color #02a774
border 1px solid #02a774
.shop_distance
clearFix()
width 100%
font-size 12px
.shop_delivery_msg
float left
transform-origin 0
transform scale(.9)
width: 200px
color #666
.segmentation
color #ccc
</style>
温馨提示:未注册硅谷外卖帐号的手机号,登录时将自动注册,且代表已同意
《用户服务协议》
登录
关于我们
<script>
export default {
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.loginContainer
width 100%
height 100%
background #fff
.loginInner
padding-top 60px
width 80%
margin 0 auto
.login_header
.login_logo
font-size 40px
font-weight bold
color #02a774
text-align center
.login_header_title
padding-top 40px
text-align center
>a
color #333
font-size 14px
padding-bottom 4px
&:first-child
margin-right 40px
&.on
color #02a774
font-weight 700
border-bottom 2px solid #02a774
.login_content
>form
>div
display none
&.on
display block
input
width 100%
height 100%
padding-left 10px
box-sizing border-box
border 1px solid #ddd
border-radius 4px
outline 0
font 400 14px Arial
&:focus
border 1px solid #02a774
.login_message
position relative
margin-top 16px
height 48px
font-size 14px
background #fff
.get_verification
position absolute
top 50%
right 10px
transform translateY(-50%)
border 0
color #ccc
font-size 14px
background transparent
.login_verification
position relative
margin-top 16px
height 48px
font-size 14px
background #fff
.switch_button
font-size 12px
border 1px solid #ddd
border-radius 8px
transition background-color .3s,border-color .3s
padding 0 6px
width 30px
height 16px
line-height 16px
color #fff
position absolute
top 50%
right 10px
transform translateY(-50%)
&.off
background #fff
.switch_text
float right
color #ddd
&.on
background #02a774
>.switch_circle
//transform translateX(27px)
position absolute
top -1px
left -1px
width 16px
height 16px
border 1px solid #ddd
border-radius 50%
background #fff
box-shadow 0 2px 4px 0 rgba(0,0,0,.1)
transition transform .3s
.login_hint
margin-top 12px
color #999
font-size 14px
line-height 20px
>a
color #02a774
.login_submit
display block
width 100%
height 42px
margin-top 30px
border-radius 4px
background #4cd96f
color #fff
text-align center
font-size 16px
line-height 42px
border 0
.about_us
display block
font-size 12px
margin-top 20px
text-align center
color #999
.go_back
position absolute
top 5px
left 5px
width 30px
height 30px
>.iconfont
font-size 20px
color #999
</style>
/* ajax **请求函数模块 */
import axios from 'axios'
export default function ajax(url = '', data = {}, type = 'GET') {
return new Promise(function(resolve, reject) {
let promise
if (type === 'GET') {
// 准备 url query 参数数据
let dataStr = '' // 数据拼接字符串
Object.keys(data).forEach(key => {
dataStr += key + '=' + data[key] + '&'
})
if (dataStr !== '') {
dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))
url = url + '?' + dataStr
}
// 发送 get 请求
promise = axios.get(url)
} else {
// 发送 post 请求
promise = axios.post(url, data)
}
promise.then(response => {
resolve(response.data)
})
.catch(error => {
reject(error)
})
})
}
/* 与后台交互模块 /
import ajax from './ajax'
/ 获取地址信息(根据经纬度串) /
export const reqAddress = geohash => ajax('/api/position/' + geohash)
/ 获取 msite 页面食品分类列表 /
export const reqCategorys = () => ajax('/api/index_category')
/ 获取 msite 商铺列表(根据经纬度) /
export const reqShops = ({latitude, longitude}) => ajax('/api/shops', {latitude, longitude})
/ 账号密码登录 /
export const reqPwdLogin = (name, pwd, captcha) => ajax('/api/login_pwd', {name, pwd, captcha}, 'POST')
/ 获取短信验证码 /
export const reqSendCode = phone => ajax('/api/sendcode', {phone})
/ 手机号验证码登录 /
export const reqSmsLogin = (phone, code) => ajax('/api/login_sms', {phone, code}, 'POST')
/ 获取用户信息(根据会话) /
export const reqUser = () => ajax('/api/userinfo')
/ 请求登出 */
export const reqLogout = () => ajax('/api/logout')
export default {
latitude: 40.10038, // 纬度
longitude: 116.36867, // 经度
address: {}, // 地址信息对象
categorys: [], // 分类数组
shops: [], //商家数组
}
/* mutation type 常量名称模块 */
// 接收地址信息
export const RECEIVE_ADDRESS = 'receive_address'
// 接收分类数组
export const RECEIVE_CATEGORYS = 'receive_categorys'
// 接收商家数组
export const RECEIVE_SHOPS = 'receive_shops'
store/mutations.js
/*
vuex 的 mutations 模块
/* vuex 的 mutations 模块 */
import {
RECEIVE_ADDRESS,
RECEIVE_CATEGORYS,
RECEIVE_SHOPS
} from './mutation-types'
export default {
[RECEIVE_ADDRESS](state, {address}) {
state.address = address
},
[RECEIVE_CATEGORYS](state, {categorys}) {
state.categorys = categorys
},
[RECEIVE_SHOPS](state, {shops}) {
state.shops = shops
}
}
store/actions.js
/* vuex 的 actions 模块 */
import {reqAddress, reqCategorys, reqShops} from '../api'
import {RECEIVE_ADDRESS, RECEIVE_CATEGORYS, RECEIVE_SHOPS} from './mutation-types'
export default {
// 异步获取地址
async getAddress({commit, state}) {
const geohash = state.latitude + ',' + state.longitude
const result = await reqAddress(geohash)
commit(RECEIVE_ADDRESS, {address: result.data})
},
// 异步获取分类列表
async getCategorys({commit}) {
const result = await reqCategorys()
commit(RECEIVE_CATEGORYS, {categorys: result.data})
},
// 异步获取商家列表
async getShops({commit, state}) {
const {latitude, longitude} = state
const result = await reqShops({latitude, longitude})
commit(RECEIVE_SHOPS, {shops: result.data})
}
}
/ *
vuex 的核心管理对象 store 对象模块
*/
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
登录|注册
<script>
import {mapState} from 'vuex'
import Swiper from 'swiper'
import 'swiper/swiper.min.css'
import ShopList from '../../components/ShopList/ShopList.vue'
import HeaderTop from '../../components/HeaderTop/HeaderTop.vue'
export default {
components: {
HeaderTop,
ShopList
},
data() {
return {
imgBaseUrl: 'https://fuss10.elemecdn.com '
}
},
mounted() {
this.$store.dispatch('getCategorys')
this.$store.dispatch('getShops')
},
computed: {
...mapState(['address', 'categorys']),
categorysArr() {
const max = 8
const arr = []
const {categorys} = this
let smallArr = []
categorys.forEach((c, index) => {
if (smallArr.length === 0) {
arr.push(smallArr)
}
smallArr.push(c)
if (smallArr.length === max) {
smallArr = []
}
})
return arr
}},
watch: {
categorys(value) {
this.$nextTick(() => {
/* eslint-disable no-new */
new Swiper('.swiper-container', {
pagination: {
el: '.swiper-pagination',
loop: true
}
})
})
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.msite
width 100%
.header
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.icon-sousuo
font-size 25px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 50%
color #fff
text-align center
.header_title_text
font-size 20px
color #fff
display block
.header_login
font-size 14px
color #fff
position absolute
right 15px
top 50%
transform translateY(-50%)
.header_login_text
color #fff
.msite_nav
bottom-border-1px(#e4e4e4)
margin-top 45px
height 200px
background #fff
.swiper-container
width 100%
height 100%
.swiper-wrapper
width 100%
height 100%
.swiper-slide
display flex
justify-content center
align-items flex-start
flex-wrap wrap
.link_to_food
width 25%
.food_container
display block
width 100%
text-align centerpadding-bottom 10px
font-size 0
img
display inline-block
width 50px
height 50px
span
display block
width 100%
text-align center
font-size 13px
color #666
.swiper-pagination
>span.swiper-pagination-bullet-active
background #02a774
.msite_shop_list
top-border-1px(#e4e4e4)
margin-top 10px
background #fff
.shop_header
padding 10px 10px 0 10px
.shop_icon
margin-left 5px
color #999
.shop_header_title
color #999
font-size 14px
line-height 20px
.shop_container
margin-bottom 50px
.shop_list
.shop_li
bottom-border-1px(#f1f1f1)
width 100%
>a
clearFix()
display block
box-sizing border-box
padding 15px 8px
width 100%
.shop_left
float left
box-sizing border-box
width 23%
height 75px
padding-right 10px
.shop_img
display block
width 100%
height 100%
.shop_right
float right
width 77%
.shop_detail_header
clearFix()
width 100%
.shop_title
text_ellipsis()
float left
width 200px
color #333
font-size 16px
line-height 16px
font-weight 700
&::before
content '品牌'
display inline-block
font-size 11px
line-height 11px
color #333
background-color #ffd930
padding 2px 2px
border-radius 2px
margin-right 5px
.shop_detail_ul
float right
margin-top 3px
.supports
float left
font-size 10px
color #999
border 1px solid #f1f1f1
padding 0 2px
border-radius 2px
.shop_rating_order
clearFix()
width 100%
margin-top 18px
margin-bottom 8px
.shop_rating_order_left
float left
color #ff9a0d
.star //2x 图 3x 图
float left
font-size 0
.star-item
display inline-block
background-repeat no-repeat
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right: 0
&.on
bg-image('./images/stars/star48_on')
&.half
bg-image('./images/stars/star48_half')
&.off
bg-image('./images/stars/star48_off')
&.star-36
.star-item
width 15px
height 15px
margin-right 6px
background-size 15px 15px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star36_on')
&.half
bg-image('./images/stars/star36_half')
&.off
bg-image('./images/stars/star36_off')
&.star-24
.star-item
width 10px
height 10px
margin-right 3px
background-size 10px 10px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star24_on')
&.half
bg-image('./images/stars/star24_half')
&.off
bg-image('./images/stars/star24_off')
.rating_section
float left
font-size 10px
color #ff6000
margin-left 4px
.order_section
float left
font-size 10px
color #666
transform scale(.8)
.shop_rating_order_right
float right
font-size 0
.delivery_style
transform-origin 35px 0
transform scale(.7)
display inline-block
font-size 12px
padding 1px
border-radius 2px
.delivery_left
color #fff
margin-right -10px
background-color #02a774
border 1px solid #02a774
.delivery_right
color #02a774
border 1px solid #02a774
.shop_distance
clearFix()
width 100%
font-size 12px
.shop_delivery_msg
float left
transform-origin 0
transform scale(.9)
width: 200px
color #666
.segmentation
color #ccc
</style>
<script>
import HeaderTop from '../../components/HeaderTop/HeaderTop.vue'
export default {
components: {
HeaderTop
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.search //搜索
width 100%
height 100%
.header //头部公共 css
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.iconfont
font-size 22px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 30%
color #fff
font-size 22px
text-align center
.search_form
clearFix()
margin-top 45px
background-color #fff
padding 12px 8px
input
height 35px
padding 0 4px
border-radius 2px
font-weight bold
outline none
&.search_input
float left
width 79%
border 4px solid #f2f2f2
font-size 14px
color #333
background-color #f2f2f2
&.search_submit
float right
width 18%
border 4px solid #02a774
font-size 16px
color #fff
background-color #02a774
</style>
{{item.rating}}
月售{{item.recent_order_num}}单
{{item.delivery_mode.text}}
¥{{item.float_minimum_order_amount}}
/
{{item.piecewise_agent_fee.tips}}
<script>
import {mapState} from 'vuex'
export default {
data() {
return {
imgBaseUrl: 'http://cangdu.org:8001/img/ '
}
},
computed: {
...mapState(['shops'])
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.shop_container
margin-bottom 50px
.shop_list
.shop_li
bottom-border-1px(#f1f1f1)
width 100%
>a
clearFix()
display block
box-sizing border-box
padding 15px 8px
width 100%
.shop_left
float left
box-sizing border-box
width 23%
height 75px
padding-right 10px
.shop_img
display block
width 100%
height 100%
.shop_right
float right
width 77%
.shop_detail_header
clearFix()
width 100%
.shop_title
text_ellipsis()
float left
width 200px
color #333
font-size 16px
line-height 16px
font-weight 700
&::before
content '品牌'
display inline-block
font-size 11px
line-height 11px
color #333
background-color #ffd930
padding 2px 2px
border-radius 2px
margin-right 5px
.shop_detail_ul
float right
margin-top 3px
.supports
float left
font-size 10px
color #999
border 1px solid #f1f1f1
padding 0 2px
border-radius 2px
.shop_rating_order
clearFix()
width 100%
margin-top 18px
margin-bottom 8px
.shop_rating_order_left
float left
color #ff9a0d
.star //2x 图 3x 图
float left
font-size 0
.star-item
display inline-block
background-repeat no-repeat
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right: 0
&.on
bg-image('./images/stars/star48_on')
&.half
bg-image('./images/stars/star48_half')
&.off
bg-image('./images/stars/star48_off')
&.star-36
.star-item
width 15px
height 15px
margin-right 6px
background-size 15px 15px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star36_on')
&.half
bg-image('./images/stars/star36_half')
&.off
bg-image('./images/stars/star36_off')
&.star-24
.star-item
width 10px
height 10px
margin-right 3px
background-size 10px 10px
&:last-child
margin-right 0
&.on
bg-image('./images/stars/star24_on')
&.half
bg-image('./images/stars/star24_half')
&.off
bg-image('./images/stars/star24_off')
.rating_section
float left
font-size 10px
color #ff6000
margin-left 4px
.order_section
float left
font-size 10px
color #666
transform scale(.8)
.shop_rating_order_right
float right
font-size 0
.delivery_style
transform-origin 35px 0
transform scale(.7)
display inline-block
font-size 12px
padding 1px
border-radius 2px
.delivery_left
color #fff
margin-right -10px
background-color #02a774
border 1px solid #02a774
.delivery_right
color #02a774
border 1px solid #02a774
.shop_distance
clearFix()
width 100%
font-size 12px
.shop_delivery_msg
float left
transform-origin 0
transform scale(.9)
width: 200px
color #666
.segmentation
color #ccc
</style>
<script>
// 类名常量
const CLASS_ON = 'on'
const CLASS_HALF = 'half'
const CLASS_OFF = 'off'
export default {
props: {
score: Number,
size: Number
},
computed: {
/*
3.2: 3 + 0 + 2
3.5: 3 + 1 + 1
*/
starClasses() {
const {score} = this
const scs = []
// 向scs中添加n个CLASS_ON
const scoreInteger = Math.floor(score)
for (let i = 0; i < scoreInteger; i++) {
scs.push(CLASS_ON)
}
// 向scs中添加0/1个CLASS_HALF
if (score * 10 - scoreInteger * 10 >= 5) {
scs.push(CLASS_HALF)
}
// 向scs中添加n个CLASS_OFF
while (scs.length < 5) {
scs.push(CLASS_OFF)
}
return scs
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.star //2x图 3x图
float left
font-size 0
.star-item
display inline-block
background-repeat no-repeat
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right: 0
&.on
bg-image('./images/star48_on')
&.half
bg-image('./images/star48_half')
&.off
bg-image('./images/star48_off')
&.star-36
.star-item
width 15px
height 15px
margin-right 6px
background-size 15px 15px
&:last-child
margin-right 0
&.on
bg-image('./images/star36_on')
&.half
bg-image('./images/star36_half')
&.off
bg-image('./images/star36_off')
&.star-24
.star-item
width 10px
height 10px
margin-right 3px
background-size 10px 10px
&:last-child
margin-right 0
&.on
bg-image('./images/star24_on')
&.half
bg-image('./images/star24_half')
&.off
bg-image('./images/star24_off')
</style>
components/AlertTip/AlertTip.vue
<script>
export default {
props: {
alertText: String
},
methods: {
closeTip() {
this.$emit('closeTip')
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import '../../common/stylus/mixins.styl';
@keyframes tipMove
0%
transform: scale(1)
35%
transform: scale(.8)
70%
transform: scale(1.1)
100%
transform: scale(1)
.alert_container
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 200;
background: rgba(0, 0, 0, .5)
.tip_text_container
position: absolute;
top: 50%;
left: 50%;
margin-top: -90px
margin-left: -110px
width: 60%
animation: tipMove .4s;
background-color: rgba(255, 255, 255, 1);
border: 1px;
padding-top: 20px
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
border-radius: 5px
.tip_icon
width: 55px
height: 55px
border: 2px solid #f8cb86;
border-radius: 50%;
font-size 20px
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
span:nth-of-type(1)
width: 2px
height: 30px
background-color: #f8cb86;
span:nth-of-type(2)
width: 2px
height: 2px
border: 1px;
border-radius: 50%;
margin-top: 2px
background-color #f8cb86
.tip_text
font-size 14px
color #333
line-height 20px
text-align center
margin-top 10px
padding 0 5px
.confrim
font-size 18px
font-weight bold
margin-top 10px
background-color #4cd964
width 100%
text-align center
line-height 35px
border 1px
color #fff
border-bottom-left-radius 5px
border-bottom-right-radius 5px
</style>
{{computeTime > 0 ? computeTime + 'S' : '获取验证码'}}
温馨提示:未注册硅谷外卖帐号的手机号,登录时将自动注册,且代表已同意
《用户服务协议》
{{showPassword ? 'abc' : '...'}}
登录
关于我们
<script>
import {reqPwdLogin, reqSendCode, reqSmsLogin} from '../../api'
import AlertTip from '../../components/AlertTip/AlertTip.vue'
export default {
data() {
return {
loginWay: true, // true 代表密码登陆, false 代表短信登陆
computeTime: 0,
showPassword: false, // 是否显示密码
phone: '', // 手机号
code: '', // 短信验证码
name: '', // 密码
pwd: '', // 密码
captcha: '', // 图形验证码
showAlert: false, // 是否显示提示框
alertText: '' // 提示框文本
}
},
mounted() {
this.name = ''
this.pwd = ''
},
computed: {
rightPhone() {
return /^1\d{10}$/.test(this.phone)
}
},
methods: {
// 获取短信验证码
async getCode() {
if (this.computeTime === 0) {
// 开始倒计时
this.computeTime = 60
// 启动循环定时器, 每隔 1s 减少 1
this.intervalId = setInterval(() => {
this.computeTime--
// 如果到时, 停止计时
if (this.computeTime === 0) {
clearInterval(this.intervalId)
}
}, 1000)
// 发送 ajax 请求(请求后台向指定手机号发验证码短信)
// 发送短信验证码
let result = await reqSendCode(this.phone)
if (result.code === 1) {
// 显示提示框
this.showAlert = true
this.alertText = result.msg
// 停止倒计时
if (this.computeTime) {
this.computeTime = 0
clearInterval(this.intervalId)
}
}
}
},
// 获取图形验证码
getCaptcha() {
this.$refs.captcha.src = 'http://localhost:4000/captcha?time=' + Date.now()
},
// 关闭提示框
closeTip() {
this.showAlert = false
this.alertText = ''
},
// 发送登录信息
async login() {
// debugger
if (!this.loginWay) {
if (!this.rightPhone) {
this.showAlert = true
this.alertText = '手机号码不正确'
return
} else if (!(/^\d{6}$/gi.test(this.code))) {
this.showAlert = true
this.alertText = '短信验证码不正确'
return
}
// 手机号短信登录
const result = await reqSmsLogin(this.phone, this.code)
if (result.code === 0) {
this.userInfo = result.data
} else {
this.userInfo = {
msg: '登陆失败, 手机号或验证不正确'
}
}
} else {
if (!this.name) {
this.showAlert = true
this.alertText = '请输入手机号/邮箱/用户名'
return
} else if (!this.pwd) {
this.showAlert = true
this.alertText = '请输入密码'
return
} else if (!this.captcha) {
this.showAlert = true
this.alertText = '请输入验证码'
return
}
// 用户名登录
const result = await reqPwdLogin(this.name, this.pwd, this.captcha)
if (result.code === 0) {
this.userInfo = result.data
} else {
this.userInfo = {
msg: result.msg
}
}
}
// 如果返回的值不正确,则弹出提示框,返回的值正确则返回上一页
if (!this.userInfo._id) {
this.showAlert = true
this.alertText = this.userInfo.msg
if (!this.loginWay) {
this.getCaptcha()
}
} else {
this.$store.dispatch('recordUserInfo', this.userInfo)
this.$router.back()
}
}
},
components: {
AlertTip
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.loginContainer
width 100%
height 100%
background #fff
.loginInner
padding-top 60px
width 80%
margin 0 auto
.login_header
.login_logo
font-size 40px
font-weight bold
color #02a774
text-align center
.login_header_title
padding-top 40px
text-align center
>a
color #333
font-size 14px
padding-bottom 4px
&:first-child
margin-right 40px
&.on
color #02a774
font-weight 700
border-bottom 2px solid #02a774
.login_content
>form
>div
display none
&.on
display block
input
width 100%
height 100%
padding-left 10px
box-sizing border-box
border 1px solid #ddd
border-radius 4px
outline 0
font 400 14px Arial
&:focus
border 1px solid #02a774
.login_message
position relative
margin-top 16px
height 48px
font-size 14px
background #fff
.get_verification
position absolute
top 50%
right 10px
transform translateY(-50%)
border 0
color #ccc
font-size 14px
background transparent
.login_verification
position relative
margin-top 16px
height 48px
font-size 14px
background #fff
.switch_button
font-size 12px
border 1px solid #ddd
border-radius 8px
transition background-color .3s,border-color .3s
padding 0 6px
width 30px
height 16px
line-height 16px
color #fff
position absolute
top 50%
right 10px
transform translateY(-50%)
&.off
background #fff
.switch_text
float right
color #ddd
&.on
background #02a774
>.switch_circle
//transform translateX(27px)
position absolute
top -1px
left -1px
width 16px
height 16px
border 1px solid #ddd
border-radius 50%
background #fff
box-shadow 0 2px 4px 0 rgba(0,0,0,.1)
transition transform .3s
.login_hint
margin-top 12px
color #999
font-size 14px
line-height 20px
>a
color #02a774
.login_submit
display block
width 100%
height 42px
margin-top 30px
border-radius 4px
background #4cd96f
color #fff
text-align center
font-size 16px
line-height 42px
border 0
.about_us
display block
font-size 12px
margin-top 20px
text-align center
color #999
.go_back
position absolute
top 5px
left 5px
width 30px
height 30px
>.iconfont
font-size 20px
color #999
</style>
<script>
import ShopHeader from '../../components/ShopHeader/ShopHeader.vue'
export default {
components: {
ShopHeader
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.tab
height 40px
line-height 40px
background #fff
bottom-border-1px(rgba(7, 17, 27, 0.1))
.tab-item
float left
width: 33.33333%
text-align center
font-size 14px
color rgb(77, 85, 93)
a
display block
position relative
&.router-link-active
color #02a774
&::after
content ''
position absolute
left 50%
bottom 1px
width 35px
height 2px
transform translateX(-50%)
background #02a774
</style>
ShopHeader
5
月售 100 单
硅谷专送
约 30 分钟
距离 1000m
是以粥为特色的中式营养快餐,自 2004 年 10 月 18 日创立“嘉和一品”品牌至今
首单
新用户下单立减 17 元(不与其它活动同享)
满减
满 35 减 19,满 65 减 35
特价
【立减 19.5 元】欢乐小食餐
首单
新用户下单立减 17 元(不与其它活动同享)
满减
满 35 减 19,满 65 减 35
特价
【立减 19.5 元】欢乐小食餐
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.shop-header
height 100%
position relative
background #fff
color #fff
overflow hidden
.shop-nav
background-size cover
background-repeat no-repeat
height 40px
padding 5px 10px
position relative
background-image
url("https://fuss10.elemecdn.com/f/5c/ead54394c3de198d3e6d3e9111bbfpng.png ")
&::before
content ""
position absolute
left 0
right 0
top 0
bottom 0
background-color rgba(119, 103, 137, .43)
.back
position: absolute
top: 10px
left: 0
.icon-arrow_left
display: block
padding: 5px
font-size: 20px
color: #fff
.shop-content
padding 30px 20px 5px 20px
position relative
display flex
background #fff
text-align center
img
box-shadow: 0 0 0.4vw 0 rgba(0, 0, 0, .2);
position: absolute;
top: 0;
left: 50%;
width: 66px
height: 66px
border-radius: 2px
margin-left -33px
margin-top -40px
.header-content
flex 1
width 72%
.content-title
font-size 20px
line-height 24px
font-weight 700
white-space nowrap
position relative
display flex
align-items center
justify-content center
color #333
.content-tag
border-radius 2px
background-image linear-gradient(90deg, #fff100, #ffe339)
width 36px
height: 18px
margin-right 10px
color #6a3709
font-style normal
font-weight 700
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
font-weight 600
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.content-name
font-weight 700
text-align left
overflow hidden
text-overflow ellipsis
.content-icon
width 20px
position relative
height 16px
&::after
content ""
border-style solid
border-width: 6px 0 6px 7px
border-color transparent transparent transparent rgba(0, 0, 0, .67)
position absolute
left 8px
top 3px
.shop-message
white-space nowrap
height 12px
margin-top 8px
font-size 11px
color #333
.shop-message-detail:not(:last-child)::after
content " \B7 "
opacity .2
.shop-notice
width 63%
font-size 11px
font-weight 300
color #999
overflow hidden
text-overflow ellipsis
margin 8px auto 10px
white-space nowrap
.shop-header-discounts
display flex
background #fff
border-radius 1px
border 1px solid #eee
padding 5px 7px
font-size 11px
color #666
margin 0 30px
align-items center
.discounts-left
flex 1
overflow hidden
.activity
display flex
align-items center
.content-tag
border-radius 1px
width 25px
height 13px
margin-right 5px
color #fff
font-style normal
font-weight 700
position relative
background-color rgb(112, 188, 70)
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 18px
font-weight 600
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.discounts-right
width 50px
flex-shrink 0
position relative
padding-right 10px
text-align right
&::after
content ""
display block
border-style solid
border-width 4px 4px 0
border-color rgba(0, 0, 0, .57) transparent transparent
position absolute
top 50%
transform translateY(-50%)
right 0
.shop-brief-modal
position fixed
top 0
left 0
right 0
bottom 0
display flex
justify-content center
align-items center
z-index 52
flex-direction column
color #333
.brief-modal-cover
position absolute
width 100%
height 100%
top 0
left 0
background-color rgba(0, 0, 0, .5)
z-index 1
.brief-modal-content
position relative
width 80%
padding 25px 20px
border-radius 5px
background #fff
z-index 99
display flex
flex-direction column
.content-title
font-size 20px
line-height 24px
font-weight 700
white-space nowrap
position relative
display flex
align-items center
justify-content center
> span
font-weight 600
.content-tag
border-radius 2px
background-image linear-gradient(90deg, #fff100, #ffe339)
width 36px
height: 18px
margin-right 10px
color #6a3709
font-style normal
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
brief-modal-msg
display flex
margin 20px -10px 0
> li
flex 1
text-align center
> h3
font-size 15px
font-weight 600
color #333
margin-bottom 8px
> p
font-size 12px
color #999
.brief-modal-title
position relative
text-align center
margin 15px auto 15px
width 85px
background-image linear-gradient(90deg, #fff, #333 50%, #fff)
background-size 100% 1px
background-position 50%
background-repeat no-repeat
> span
font-size 12px
padding 0 6px
color #999
background-color #fff
.brief-modal-notice
font-size 13px
line-height 1.54
color #333
overflow-y auto
.mask-footer
position absolute
bottom -60px
left 50%
padding 6px
border 1px solid rgba(255, 255, 255, .7)
border-radius 50%
transform translateX(-50%)
span
font-size 16px
color rgba(255, 255, 255, .7)
.activity-sheet
position fixed
top 0
left 0
width 100%
height 100%
z-index 99
.activity-sheet-content
position absolute
background-color #f5f5f5
box-shadow 0 -1px 5px 0 rgba(0, 0, 0, .4)
bottom 0
left 0
right 0
z-index 100
padding 20px 30px
box-sizing border-box
transition transform .2s
will-change transform
color #333
.activity-sheet-title
text-align center
font-size 20px
font-weight 600
margin-bottom 20px
.list
font-size 16px
height 160px
overflow-y auto
.activity-item
margin-bottom 12px
display flex
font-size 13px
align-items center
&.activity-green
.content-tag
background-color rgb(112, 188, 70)
&.activity-red
.content-tag
background-color rgb(240, 115, 115)
&.activity-orange
.content-tag
background-color: rgb(241, 136, 79)
.content-tag
display inline-block
border-radius 2px
width 36px
height: 18px
margin-right 10px
color #fff
font-style normal
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.activity-sheet-close
position absolute
right 6px
top 10px
width 25px
height 25px
> span
font-size 20px
.activity-sheet-cover
position absolute
width 100%
height 100%
top 0
left 0
background-color rgba(0, 0, 0, .5)
</style>
ShopHeader.vue
{{info.score}}
月售{{info.sellCount}}单
{{info.description}}
约 {{info.deliveryTime}} 分钟
距离 {{info.distance}}
{{info.supports[0].name}}
{{info.supports[0].content}}
{{info.supports.length}} 个优惠
{{support.name}}
{{support.content}}
<script>
import {mapState} from 'vuex'
export default {
data() {
return {
supportClasses: ['activity-green', 'activity-red', 'activity-orange'],
supportsShow: false,
shopShow: false
}
},
mounted() {
this.$store.dispatch('getShopInfo')
},
computed: {
...mapState(['info'])
},
methods: {
toggleSupportsShow() {
this.supportsShow = !this.supportsShow
},
toggleShopShow() {
this.shopShow = !this.shopShow
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.shop-header
height 100%
position relative
background #fff
color #fff
overflow hidden
.shop-nav
background-size cover
background-repeat no-repeat
height 40px
padding 5px 10px
position relative
background-image url("https://fuss10.elemecdn.com/f/5c/ead54394c3de198d3e6d3e9111bbfpng.png ")
&::before
content ""
position absolute
left 0
right 0
top 0
bottom 0
background-color rgba(119, 103, 137, .43)
.back
position: absolute
top: 10px
left: 0
.icon-arrow_left
display: block
padding: 5px
font-size: 20px
color: #fff
.shop-content
padding 30px 20px 5px 20px
position relative
display flex
background #fff
text-align center
img
box-shadow: 0 0 0.4vw 0 rgba(0, 0, 0, .2);
position: absolute;
top: 0;
left: 50%;
width: 66px
height: 66px
border-radius: 2px
margin-left -33px
margin-top -40px
.header-content
flex 1
width 72%
.content-title
font-size 20px
line-height 24px
font-weight 700
white-space nowrap
position relative
display flex
align-items center
justify-content center
color #333
.content-tag
border-radius 2px
background-image linear-gradient(90deg, #fff100, #ffe339)
width 36px
height: 18px
margin-right 10px
color #6a3709
font-style normal
font-weight 700
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
font-weight 600
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.content-name
font-weight 700
text-align left
overflow hidden
text-overflow ellipsis
.content-icon
width 20px
position relative
height 16px
&::after
content ""
border-style solid
border-width: 6px 0 6px 7px
border-color transparent transparent transparent rgba(0, 0, 0, .67)
position absolute
left 8px
top 3px
.shop-message
white-space nowrap
height 12px
margin-top 8px
font-size 11px
color #333
.shop-message-detail:not(:last-child)::after
content " \B7 "
opacity .2
.shop-notice
width 63%
font-size 11px
font-weight 300
color #999
overflow hidden
text-overflow ellipsis
margin 8px auto 10px
white-space nowrap
.shop-header-discounts
display flex
background #fff
border-radius 1px
border 1px solid #eee
padding 5px 7px
font-size 11px
color #666
margin 0 30px
align-items center
.discounts-left
flex 1
overflow hidden
.activity
display flex
align-items center
.content-tag
border-radius 1px
width 25px
height 13px
margin-right 5px
color #fff
font-style normal
font-weight 700
position relative
background-color rgb(112, 188, 70)
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 18px
font-weight 600
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.discounts-right
width 50px
flex-shrink 0
position relative
padding-right 10px
text-align right
&::after
content ""
display block
border-style solid
border-width 4px 4px 0
border-color rgba(0, 0, 0, .57) transparent transparent
position absolute
top 50%
transform translateY(-50%)
right 0
.shop-brief-modal
position fixed
top 0
left 0
right 0
bottom 0
display flex
justify-content center
align-items center
z-index 52
flex-direction column
color #333
.brief-modal-cover
position absolute
width 100%
height 100%
top 0
left 0
background-color rgba(0, 0, 0, .5)
z-index 1
.brief-modal-content
position relative
width 80%
padding 25px 20px
border-radius 5px
background #fff
z-index 99
display flex
flex-direction column
.content-title
font-size 20px
line-height 24px
font-weight 700
white-space nowrap
position relative
display flex
align-items center
justify-content center
> span
font-weight 600
.content-tag
border-radius 2px
background-image linear-gradient(90deg, #fff100, #ffe339)
width 36px
height: 18px
margin-right 10px
color #6a3709
font-style normal
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
brief-modal-msg
display flex
margin 20px -10px 0
> li
flex 1
text-align center
> h3
font-size 15px
font-weight 600
color #333
margin-bottom 8px
> p
font-size 12px
color #999
.brief-modal-title
position relative
text-align center
margin 15px auto 15px
width 85px
background-image linear-gradient(90deg, #fff, #333 50%, #fff)
background-size 100% 1px
background-position 50%
background-repeat no-repeat
> span
font-size 12px
padding 0 6px
color #999
background-color #fff
.brief-modal-notice
font-size 13px
line-height 1.54
color #333
overflow-y auto
.mask-footer
position absolute
bottom -60px
left 50%
padding 6px
border 1px solid rgba(255, 255, 255, .7)
border-radius 50%
transform translateX(-50%)
span
font-size 16px
color rgba(255, 255, 255, .7)
.activity-sheet
position fixed
top 0
left 0
width 100%
height 100%
z-index 99
.activity-sheet-content
position absolute
background-color #f5f5f5
box-shadow 0 -1px 5px 0 rgba(0, 0, 0, .4)
bottom 0
left 0
right 0
z-index 100
padding 20px 30px
box-sizing border-box
transition transform .2s
will-change transform
color #333
.activity-sheet-title
text-align center
font-size 20px
font-weight 600
margin-bottom 20px
.list
font-size 16px
height 160px
overflow-y auto
.activity-item
margin-bottom 12px
display flex
font-size 13px
align-items center
&.activity-green
.content-tag
background-color rgb(112, 188, 70)
&.activity-red
.content-tag
background-color rgb(240, 115, 115)
&.activity-orange
.content-tag
background-color: rgb(241, 136, 79)
.content-tag
display inline-block
border-radius 2px
width 36px
height: 18px
margin-right 10px
color #fff
font-style normal
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.activity-sheet-close
position absolute
right 6px
top 10px
width 25px
height 25px
> span
font-size 20px
.activity-sheet-cover
position absolute
width 100%
height 100%
top 0
left 0
background-color rgba(0, 0, 0, .5)
</style>
折扣
优惠
甜粥
月售 91 份
好评率 100%
¥9
CartControl
甜粥
月售 86 份
好评率 100%
¥12
CartControl
红枣山药糙米粥,素材包
月售 17 份
好评率 100%
¥29
¥36
CartControl
<style lang="stylus" rel="stylesheet/stylus">
@import "../../../common/stylus/mixins.styl"
.goods
display: flex
position: absolute
top: 195px
bottom: 46px
width: 100%
background: #fff;
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
color: $green
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
.text
display: table-cell
width: 56px
vertical-align: middle
bottom-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
bottom-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>
{{good.name}}
{{food.description}}
月售 {{food.sellCount}} 份
好评率 {{food.rating}}
¥{{food.price}}
¥{{food.oldPrice}}
CartControl
<script>
import {mapState} from 'vuex'
import BScroll from 'better-scroll'
export default{
data() {
return {
scrollY: 0, // 右侧 Y 轴滑动的坐标
tops: [] // 包含右侧所有分类小列表的 top 值
}
},
mounted() {
// 使用 axios 请求 mockjs 提供的接口
this.$store.dispatch('getShopGoods', () => {
// goods 更新了, 界面还没有更新
this.$nextTick(() => {
// 初始化滚动
this._initScroll()
// 初始化 tops
this._initTops()
})
})
},
methods: {
_initScroll() {
// 左侧分类列表的 BScroll
/* eslint-disable no-new */
new BScroll('.menu-wrapper', {
click: true // 响应点击
})
// 右侧 food 列表的 BScroll
this.foodsScroll = new BScroll('.foods-wrapper', {
probeType: 2, // 手指滑动(惯性滑动和编码滑动不监视)
click: true // 响应点击
})
// 监视滑动过程
this.foodsScroll.on('scroll', (pos) => {
console.log(pos.y)
// 保存 y
this.scrollY = Math.abs(pos.y)
})
// 监视滑动结束
this.foodsScroll.on('scrollEnd', (pos) => {
console.log('滑动结束', pos.y)
this.scrollY = Math.abs(pos.y) // 解决惯性滑动更新
})
},
_initTops() {
const tops = []
let top = 0
// 计算各个 top, 并保存到 tops
tops.push(top)
// 得到 ul 下所有的子 li
const lis = this.$refs.foodsWarpperUl.getElementsByClassName('food-list-hook')
Array.prototype.slice.call(lis).forEach((li, index) => {
top += li.clientHeight
tops.push(top)
})
// 保存 tops
this.tops = tops
console.log(this.tops)
},
clickMenuItem(index) {
// 得到滚动目标坐标
const top = this.tops[index]
// 更新目标 scrollY 值
this.scrollY = top
// 平滑滚动到指定位置
this.foodsScroll.scrollTo(0, -top, 300)
}
},
computed: {
...mapState(['goods']),
currentIndex() {
return this.tops.findIndex((top, index) => {
return this.scrollY >= top && this.scrollY < this.tops[index + 1]
})
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../../common/stylus/mixins.styl"
.goods
display: flex
position: absolute
top: 195px
bottom: 46px
width: 100%
background: #fff;
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
color: $green
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
.text
display: table-cell
width: 56px
vertical-align: middle
bottom-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
bottom-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>
components/CartControl/CartControl.vue
<script>
export default {
props: {
food: Object
},
methods: {
// 更新 food 的 count
updateFoodCount (isAdd) {
const {food} = this
// 通知 action 更新
this.$store.dispatch('updateFoodCount', {food, isAdd})
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.cartcontrol
font-size: 0
.cart-decrease
display: inline-block
padding: 6px
line-height: 24px
font-size: 24px
color: rgb(0, 160, 220)
.icon-remove_circle_outline
display: inline-block
padding 6px
line-height 24px
font-size 24px
color $green
.cart-count
display: inline-block
vertical-align: top
width: 12px
padding-top: 6px
line-height: 24px
text-align: center
font-size: 10px
color: rgb(147, 153, 159)
.icon-add_circle
display: inline-block
padding: 6px
line-height: 24px
font-size: 24px
color $green
</style>
components/ShopCart/ShopCart.vue
<script>
import BScroll from 'better-scroll'
import { mapState, mapGetters } from 'vuex'
import CartControl from '../CartControl/CartControl.vue'
export default {
data () {
return {
isShow: false
}
},
computed: {
...mapState(['info', 'shopCart']),
...mapGetters(['totalCount', 'totalPrice']),
payClass () {
const {totalPrice} = this
const {minPrice} = this.info
return totalPrice>=minPrice ? 'enough' : 'not-enough'
},
payText () {
const {totalPrice} = this
const {minPrice} = this.info
if(totalPrice===0) {
return `¥${minPrice}元起送`
} else if(totalPrice {
// 在界面更新后创建 BScroll(只能创建一个)
/*单例:
1. 在创建前, 判断是否存在,只有不存在, 才去创建
2. 创建后, 保存它
*/
if(!this.scroll) {
// 第一次打开
this.scroll = new BScroll('#listContent', {
click: true
})
} else {
// 后面打开
// 通知 scroll 对象
this.scroll.refresh()
}
})
}
// 只需要看 isShow
return this.isShow
}
},
methods: {
toggleShow () {
if(this.totalCount) { // 只有有数量时切换
this.isShow = !this.isShow
}
},
clear () {
if(window.confirm('确定要清空购物车吗?')) {
this.$store.dispatch('clearCart')
}
}
},
components: {
CartControl
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.shopcart
position fixed
left 0
bottom 0
z-index 50
width 100%
height 48px
.content
display flex
background #141d27
font-size 0
color rgba(255, 255, 255, 0.4)
.content-left
flex 1
.logo-wrapper
display inline-block
vertical-align top
position relative
top -10px
margin 0 12px
padding 6px
width 56px
height 56px
box-sizing border-box
border-radius 50%
background #141d27
.logo
width 100%
height 100%
border-radius 50%
text-align center
background #2b343c
&.highlight
background $green
.icon-shopping_cart
line-height 44px
font-size 24px
color #80858a
&.highlight
color #fff
.num
position absolute
top 0
right 0
width 24px
height 16px
line-height 16px
text-align center
border-radius 16px
font-size 9px
font-weight 700
color #ffffff
background rgb(240, 20, 20)
box-shadow 0 4px 8px 0 rgba(0, 0, 0, 0.4)
.price
display inline-block
vertical-align top
margin-top 5px
line-height 24px
padding-right 12px
box-sizing border-box
font-size 16px
font-weight 700
color #fff
&.highlight
color #fff
.desc
display inline-block
vertical-align bottom
margin-bottom 15px
margin-left -45px
font-size 10px
.content-right
flex 0 0 105px
width 105px
.pay
height 48px
line-height 48px
text-align center
font-size 12px
font-weight 700
color #fff
&.not-enough
background #2b333b
&.enough
background #00b43c
color #fff
.ball-container
.ball
position fixed
left 32px
bottom 22px
z-index 200
transition all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41)
.inner
width 16px
height 16px
border-radius 50%
background $green
transition all 0.4s linear
.shopcart-list
position absolute
left 0
top 0
z-index -1
width 100%
transform translateY(-100%)
&.swipe-enter-active, &.swipe-leave-active
transition transform .3s
&.swipe-enter, &.swipe-leave-to
transform translateY(0)
.list-header
height 40px
line-height 40px
padding 0 18px
background #f3f5f7
border-bottom 1px solid rgba(7, 17, 27, 0.1)
.title
float left
font-size 14px
color rgb(7, 17, 27)
.empty
float right
font-size 12px
color rgb(0, 160, 220)
.list-content
padding 0 18px
max-height 217px
overflow hidden
background #fff
.food
position relative
padding 12px 0
box-sizing border-box
bottom-border-1px(rgba(7, 17, 27, 0.1))
.name
line-height 24px
font-size 14px
color rgb(7, 17, 27)
.price
position absolute
right 90px
bottom 12px
line-height 24px
font-size 14px
font-weight 700
color rgb(240, 20, 20)
.cartcontrol-wrapper
position absolute
right 0
bottom 6px
.list-mask
position fixed
top 0
left 0
width 100%
height 100%
z-index 40
backdrop-filter blur(10px)
opacity 1
background rgba(7, 17, 27, 0.6)
&.fade-enter-active, &.fade-leave-active
transition all 0.5s
&.fade-enter, &.fade-leave-to
opacity 0
background rgba(7, 17, 27, 0)
</style>
主、辅料:水、大米、南瓜、冰糖等
月售 91 份
好评率 100%
¥9
¥
cartcontrol 组件
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.food
position: fixed
left: 0
top: 0
bottom: 48px
z-index: 101
width: 100%
&.fade-enter-active, &.fade-leave-active
transition opacity .5s
&.fade-enter, &.fade-leave-to
opacity 0
.food-content
position absolute
left 50%
top 50%
transform translate(-50%, -50%)
width 80%
height 65%
z-index 66
background #fff
border-radius 5px
.image-header
position: relative
width: 100%
height: 0
padding-top: 100%
img
position: absolute
top: 0
left: 0
width: 100%
height: 100%
.foodpanel-desc
font-size 10px
color #ddd
letter-spacing 0
position absolute
bottom 0
left 0
right 0
padding 0 10px 10px
.back
position: absolute
top: 10px
left: 0
.icon-arrow_left
display: block
padding: 10px
font-size: 20px
color: #fff
.content
position: relative
padding: 18px
.title
line-height: 14px
margin-bottom: 8px
font-size: 14px
font-weight: 700
color: rgb(7, 17, 27)
.detail
margin-bottom: 18px
line-height: 10px
height: 10px
font-size: 0
.sell-count, .rating
font-size: 10px
color: rgb(147, 153, 159)
.sell-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: 12px
bottom: 12px
.buy
position: absolute
right: 18px
bottom: 18px
z-index: 10
height: 24px
line-height: 24px
padding: 0 12px
box-sizing: border-box
border-radius: 12px
font-size: 10px
color: #fff
background: rgb(0, 160, 220)
&.fade-transition
transition: all 0.2s
opacity: 1
&.fade-enter, &.fade-leave
opacity: 0
.food-cover
position absolute
top 0
right 0
bottom -48px
left 0
z-index 55
background-color rgba(0, 0, 0, 0.5)`
</style>
#### Food/Food.vue2
{{food.info}}
月售{{food.sellCount}}份
好评率{{food.rating}}%
¥{{food.price}}
¥{{food.oldPrice}}
<script>
import CartControl from '../CartControl/CartControl.vue'
export default {
props: {
food: Object
},
data() {
return {
isShow: false,
}
},
methods: {
toggleShow() {
// 显示/隐藏当前 food
this.isShow = !this.isShow
},
addToCart() {
this.$store.dispatch('updateFoodCount', {food: this.food, isAdd: true})
}
},
components: {
CartControl,
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.food
position: fixed
left: 0
top: 0
bottom: 48px
z-index: 101
width: 100%
&.fade-enter-active, &.fade-leave-active
transition opacity .5s
&.fade-enter, &.fade-leave-to
opacity 0
.food-content
position absolute
left 50%
top 50%
transform translate(-50%, -50%)
width 80%
height 65%
z-index 66
background #fff
border-radius 5px
.image-header
position: relative
width: 100%
height: 0
padding-top: 100%
img
position: absolute
top: 0
left: 0
width: 100%
height: 100%
.foodpanel-desc
font-size 10px
color #ddd
letter-spacing 0
position absolute
bottom 0
left 0
right 0
padding 0 10px 10px
.back
position: absolute
top: 10px
left: 0
.icon-arrow_left
display: block
padding: 10px
font-size: 20px
color: #fff
.content
position: relative
padding: 18px
.title
line-height: 14px
margin-bottom: 8px
font-size: 14px
font-weight: 700
color: rgb(7, 17, 27)
.detail
margin-bottom: 18px
line-height: 10px
height: 10px
font-size: 0
.sell-count, .rating
font-size: 10px
color: rgb(147, 153, 159)
.sell-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: 12px
bottom: 12px
.buy
position: absolute
right: 18px
bottom: 18px
z-index: 10
height: 24px
line-height: 24px
padding: 0 12px
box-sizing: border-box
border-radius: 12px
font-size: 10px
color: #fff
background: rgb(0, 160, 220)
&.fade-transition
transition: all 0.2s
opacity: 1
&.fade-enter, &.fade-leave
opacity: 0
.food-cover
position absolute
top 0
right 0
bottom -48px
left 0
z-index 55
background-color rgba(0, 0, 0, 0.5)`
</style>
{{good.name}}
{{food.description}}
月售 {{food.sellCount}} 份
好评率 {{food.rating}}
¥{{food.price}}
¥{{food.oldPrice}}
CartControl
<script>
import {mapState} from 'vuex'
import BScroll from 'better-scroll'
import Food from '../../../components/Food/Food.vue'
export default{
components: {
Food
},
data () {
return {
food: {},
scrollY: 0, //右侧 Y 轴滑动的坐标
tops: [], // 包含右侧所有分类小列表的 top 值
}
},
mounted () {
// 使用 axios 请求 mockjs 提供的接口
this.$store.dispatch('getShopGoods', () => {
// goods 更新了, 界面还没有更新
this.$nextTick(() => {
// 初始化滚动
this._initScroll()
// 初始化 tops
this._initTops()
})
})
},
methods: {
showFood(food) {
this.food= food
this.$refs.food.toggleShow()
},
_initScroll () {
// 左侧分类列表的 BScroll
new BScroll('.menu-wrapper',{
click: true //响应点击
})
// 右侧 food 列表的 BScroll
this.foodsScroll = new BScroll('.foods-wrapper',{
probeType: 2, // 手指滑动(惯性滑动和编码滑动不监视)
click: true //响应点击
})
// 监视滑动过程
this.foodsScroll.on('scroll', (pos) => {
console.log(pos.y)
// 保存 y
this.scrollY = Math.abs(pos.y)
})
// 监视滑动结束
this.foodsScroll.on('scrollEnd',(pos) => {
console.log('滑动结束', pos.y)
this.scrollY = Math.abs(pos.y) // 解决惯性滑动更新
})
},
_initTops () {
const tops = []
let top = 0
// 计算各个 top, 并保存到 tops
tops.push(top)
// 得到 ul 下所有的子 li
const lis = this.$refs.foodsWarpperUl.getElementsByClassName('food-list-hook')
Array.prototype.slice.call(lis).forEach((li, index) => {
top += li.clientHeight
tops.push(top)
})
// 保存 tops
this.tops = tops
console.log(this.tops)
},
clickMenuItem (index) {
// 得到滚动目标坐标
const top = this.tops[index]
// 更新目标 scrollY 值
this.scrollY = top
// 平滑滚动到指定位置
this.foodsScroll.scrollTo(0, -top, 300)
}
},
computed: {
...mapState(['goods']),
currentIndex () {
return this.tops.findIndex((top, index)=> {
return this.scrollY>=top && this.scrollY
<style lang="stylus" rel="stylesheet/stylus">
@import "../../../common/stylus/mixins.styl"
.goods
display: flex
position: absolute
top: 195px
bottom: 46px
width: 100%
background: #fff;
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
color: $green
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
.text
display: table-cell
width: 56px
vertical-align: middle
bottom-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
bottom-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>
服务态度
4.6
商品评分
4.7
送达时间
30 分钟
全部
30
满意
28
不满意
2
只看有内容的评价
30
不错
南瓜粥
皮蛋瘦肉粥
扁豆焖面
2016-07-23 21:52:44
30
不错
2016-07-23 21:52:44
<style lang="stylus" rel="stylesheet/stylus">
@import "../../../common/stylus/mixins.styl"
.ratings
position: absolute
top: 195px
bottom: 0
left: 0
width: 100%
overflow: hidden
background: #fff
.overview
display: flex
padding: 18px 0
.overview-left
flex: 0 0 137px
padding: 6px 0
width: 137px
border-right: 1px solid rgba(7, 17, 27, 0.1)
text-align: center
@media only screen and (max-width: 320px)
flex: 0 0 120px
width: 120px
.score
margin-bottom: 6px
line-height: 28px
font-size: 24px
color: rgb(255, 153, 0)
.title
margin-bottom: 8px
line-height: 12px
font-size: 12px
color: rgb(7, 17, 27)
.rank
line-height: 10px
font-size: 10px
color: rgb(147, 153, 159)
.overview-right
flex: 1
padding: 6px 0 6px 24px
@media only screen and (max-width: 320px)
padding-left: 6px
.score-wrapper
margin-bottom: 8px
font-size: 0
.title
display: inline-block
line-height: 18px
vertical-align: top
font-size: 12px
color: rgb(7, 17, 27)
.star
display: inline-block
margin: 0 12px
vertical-align: top
.score
display: inline-block
line-height: 18px
vertical-align: top
font-size: 12px
color: rgb(255, 153, 0)
.delivery-wrapper
font-size: 0
.title
line-height: 18px
font-size: 12px
color: rgb(7, 17, 27)
.delivery
margin-left: 12px
font-size: 12px
color: rgb(147, 153, 159)
.split
width: 100%
height: 16px
border-top: 1px solid rgba(7, 17, 27, 0.1)
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
background: #f3f5f7
.ratingselect
.rating-type
padding: 18px 0
margin: 0 18px
border-1px(rgba(7, 17, 27, 0.1))
font-size: 0
.block
display: inline-block
padding: 8px 12px
margin-right: 8px
line-height: 16px
border-radius: 1px
font-size: 12px
color: rgb(77, 85, 93)
background: rgba(77, 85, 93, 0.2)
&.active
background: $green
color: #fff
.count
margin-left: 2px
font-size: 8px
.switch
padding: 12px 18px
line-height: 24px
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
color: rgb(147, 153, 159)
font-size: 0
&.on
.icon-check_circle
color: $green
.icon-check_circle
display: inline-block
vertical-align: top
margin-right: 4px
font-size: 24px
.text
display: inline-block
vertical-align: top
font-size: 12px
.rating-wrapper
padding: 0 18px
.rating-item
display: flex
padding: 18px 0
bottom-border-1px(rgba(7, 17, 27, 0.1))
.avatar
flex: 0 0 28px
width: 28px
margin-right: 12px
img
border-radius: 50%
.content
position: relative
flex: 1
.name
margin-bottom: 4px
line-height: 12px
font-size: 10px
color: rgb(7, 17, 27)
.star-wrapper
margin-bottom: 6px
font-size: 0
.star
display: inline-block
margin-right: 6px
vertical-align: top
.delivery
display: inline-block
vertical-align: top
line-height: 12px
font-size: 10px
color: rgb(147, 153, 159)
.text
margin-bottom: 8px
line-height: 18px
color: rgb(7, 17, 27)
font-size: 12px
.recommend
line-height: 16px
font-size: 0
.icon-thumb_up, .icon-thumb_down, .item
display: inline-block
margin: 0 8px 4px 0
font-size: 9px
.icon-thumb_up
color: $yellow
.icon-thumb_down
color: rgb(147, 153, 159)
.item
padding: 0 6px
border: 1px solid rgba(7, 17, 27, 0.1)
border-radius: 1px
color: rgb(147, 153, 159)
background: #fff
.time
position: absolute
top: 0
right: 0
line-height: 12px
font-size: 10px
color: rgb(147, 153, 159)
</style>
综合评分
高于周边商家{{info.rankRate}}%
服务态度
{{info.serviceScore}}
商品评分
{{info.foodScore}}
送达时间
{{info.deliveryTime}}分钟
全部
{{ratings.length}}
满意
{{positiveCount}}
不满意
{{ratings.length-positiveCount}}
只看有内容的评价
{{rating.deliveryTime}}
{{rating.text}}
{{item}}
{{rating.rateTime | dateString}}
<script>
import { mapState } from 'vuex'
import BScroll from 'better-scroll'
import Star from '../../../components/Star/Star.vue'
import Split from '../../../components/Split/Split.vue'
export default {
data () {
return {
selectType: 0,
onlyContent: false
}
},
computed: {
...mapState(['info', 'ratings']),
// 好评数量
positiveCount (state) {
return state.ratings.reduce((preTotal, rating) => {
return preTotal + (rating.rateType===0 ? 1 : 0)
}, 0)
},
// 过滤后评价数组
filterRatings () {
const ratings = this.ratings
if (!ratings) {
return []
}
const {selectType, onlyContent} = this
return ratings.filter(rating => {
const {rateType, text} = rating
/*
selectType: 2, //全部 // rating.rateType(0/1)
onlyContent: true // 是否只看有内容的 //rating.text
*/
/*
selectType: 0/1/2 如果是 0/1 需要判断是否与 rating.rateType 相等, 如果是 2 就不
需要
onlyContent: true/false 如果为 true 需要判断 rating.text 必须有值, 如果是 false
就不需要
*/
if (selectType === 2) {
return !onlyContent || rating.text.length > 0
} else {
return selectType === rateType && (!onlyContent || rating.text.length > 0)
}
})
}
},
mounted () {
this.$store.dispatch('getShopRatings', () => {
this.$nextTick(() => {
this.scroll = new BScroll(this.$refs.ratings, {
click: true
})
})
})
},
methods: {
setSelectType (selectType) {
this.selectType = selectType
this.$nextTick(() => {
this.scroll.refresh()
})
},
toggleOnlyContent () {
this.onlyContent = !this.onlyContent
this.$nextTick(() => {
this.scroll.refresh()
})
}
},
components: {
Star,
Split
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../../common/stylus/mixins.styl"
.ratings
position: absolute
top: 195px
bottom: 0
left: 0
width: 100%
overflow: hidden
background: #fff
.overview
display: flex
padding: 18px 0
.overview-left
flex: 0 0 137px
padding: 6px 0
width: 137px
border-right: 1px solid rgba(7, 17, 27, 0.1)
text-align: center
@media only screen and (max-width: 320px)
flex: 0 0 120px
width: 120px
.score
margin-bottom: 6px
line-height: 28px
font-size: 24px
color: rgb(255, 153, 0)
.title
margin-bottom: 8px
line-height: 12px
font-size: 12px
color: rgb(7, 17, 27)
.rank
line-height: 10px
font-size: 10px
color: rgb(147, 153, 159)
.overview-right
flex: 1
padding: 6px 0 6px 24px
@media only screen and (max-width: 320px)
padding-left: 6px
.score-wrapper
margin-bottom: 8px
font-size: 0
.title
display: inline-block
line-height: 18px
vertical-align: top
font-size: 12px
color: rgb(7, 17, 27)
.star
display: inline-block
margin: 0 12px
vertical-align: top
.score
display: inline-block
line-height: 18px
vertical-align: top
font-size: 12px
color: rgb(255, 153, 0)
.delivery-wrapper
font-size: 0
.title
line-height: 18px
font-size: 12px
color: rgb(7, 17, 27)
.delivery
margin-left: 12px
font-size: 12px
color: rgb(147, 153, 159)
.split
width: 100%
height: 16px
border-top: 1px solid rgba(7, 17, 27, 0.1)
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
background: #f3f5f7
.ratingselect
.rating-type
padding: 18px 0
margin: 0 18px
border-1px(rgba(7, 17, 27, 0.1))
font-size: 0
.block
display: inline-block
padding: 8px 12px
margin-right: 8px
line-height: 16px
border-radius: 1px
font-size: 12px
color: rgb(77, 85, 93)
background: rgba(77, 85, 93, 0.2)
&.active
background: $green
color: #fff
.count
margin-left: 2px
font-size: 8px
.switch
padding: 12px 18px
line-height: 24px
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
color: rgb(147, 153, 159)
font-size: 0
&.on
.icon-check_circle
color: $green
.icon-check_circle
display: inline-block
vertical-align: top
margin-right: 4px
font-size: 24px
.text
display: inline-block
vertical-align: top
font-size: 12px
.rating-wrapper
padding: 0 18px
.rating-item
display: flex
padding: 18px 0
bottom-border-1px(rgba(7, 17, 27, 0.1))
.avatar
flex: 0 0 28px
width: 28px
margin-right: 12px
img
border-radius: 50%
.content
position: relative
flex: 1
.name
margin-bottom: 4px
line-height: 12px
font-size: 10px
color: rgb(7, 17, 27)
.star-wrapper
margin-bottom: 6px
font-size: 0
.star
display: inline-block
margin-right: 6px
vertical-align: top
.delivery
display: inline-block
vertical-align: top
line-height: 12px
font-size: 10px
color: rgb(147, 153, 159)
.text
margin-bottom: 8px
line-height: 18px
color: rgb(7, 17, 27)
font-size: 12px
.recommend
line-height: 16px
font-size: 0
.icon-thumb_up, .icon-thumb_down, .item
display: inline-block
margin: 0 8px 4px 0
font-size: 9px
.icon-thumb_up
color: $yellow
.icon-thumb_down
color: rgb(147, 153, 159)
.item
padding: 0 6px
border: 1px solid rgba(7, 17, 27, 0.1)
border-radius: 1px
color: rgb(147, 153, 159)
background: #fff
.time
position: absolute
top: 0
right: 0
line-height: 12px
font-size: 10px
color: rgb(147, 153, 159)
</style>
硅谷专送
由商家配送提供配送,约 40 分钟送达,距离 100m
配送费¥5
首单
新用户下单立减 17 元(不与其它活动同享)
满减
满 35 减 19,满 65 减 35
特价
【立减 19.5 元】欢乐小食餐
品类 包子粥店
商家电话 13301083744
地址 北京市丰台区
营业时间 08:35-23:00
<style lang="stylus" rel="stylesheet/stylus">
@import "../../../common/stylus/mixins.styl"
.shop-info
position: absolute
top: 195px
bottom: 0
left: 0
width: 100%
background: #fff;
overflow: hidden
.section
padding 16px 14px 14px
font-size 16px
background-color #fff
color #666
border-bottom 1px solid #eee
position relative
.section-title
color #000
font-weight 700
line-height 16px
> .iconfont
float right
color #ccc
.delivery
margin-top 16px
font-size 13px
line-height 18px
.delivery-icon
width 55px
font-size 11px
margin-right 10px
display inline-block
text-align center
color #fff
background-color #0097ff
padding 1px 0
border-radius 4px
.delivery-money
margin-top 5px
.activity
margin-top 16px
.activity-item
margin-bottom 12px
display flex
font-size 13px
align-items center
&.activity-green
.content-tag
background-color rgb(112, 188, 70)
&.activity-red
.content-tag
background-color rgb(240, 115, 115)
&.activity-orange
.content-tag
background-color: rgb(241, 136, 79)
.content-tag
display inline-block
border-radius 2px
width 36px
height: 18px
margin-right 10px
color #fff
font-style normal
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.pic-wrapper
width: 100%
overflow: hidden
white-space: nowrap
margin-top 16px
.pic-list
font-size: 0
.pic-item
display: inline-block
margin-right: 6px
width: 120px
height: 90px
&:last-child
margin: 0
.detail
margin-bottom -16px
> li
display flex
justify-content space-between
align-items center
margin-right -10px
padding 16px 12px 16px 0
line-height 16px
bottom-border-1px(#ddd)
font-size 13px
> .bold
font-weight 700
color #333
&:last-child
border-none()
.split
width: 100%
height: 16px
border-top: 1px solid rgba(7, 17, 27, 0.1)
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
background: #f3f5f7
</style>
#### ShopInfo2
{{info.description}}
由商家配送提供配送,约 {{info.deliveryTime}} 分钟送达,距离 {{info.distance}}
配送费¥{{info.deliveryPrice}}
{{support.name}}
{{support.content}}
品类 {{info.category}}
商家电话 {{info.phone}}
地址 {{info.address}}
营业时间 {{info.workTime}}
<script>
import BScroll from 'better-scroll'
import {mapState} from 'vuex'
import Star from '../../../components/Star/Star.vue'
export default {
data() {
return {
favorite: localStorage.getItem('favorite') === 'true',
supportClasses: ['activity-green', 'activity-red', 'activity-orange'],
}
},
// 此时 info 可能是一个空对象, 也可能是一个带数据的对象
mounted() {
this.$nextTick(() => {
this.ratingsSroll = new BScroll(this.$refs.info, {click: true})
this.picsScroll = new BScroll(this.$refs.pics, {click: true, scrollX: true})
// 指定图片 ul 的样式宽度(前提是有数据)
this.info.pics && this.setUlWidth()
})
},
watch: {
info() { // info 状态数据更新了, 但界面还没有真正更新
this.$nextTick(() => {
this.ratingsSroll.refresh()
this.setUlWidth()
this.picsScroll.refresh()
})
}
},
computed: {
...mapState(['info'])
},
methods: {
toggleFavorite() {
this.favorite = !this.favorite
// 保存状态
localStorage.setItem('favorite', this.favorite)
},
setUlWidth() {
const ul = this.$refs.ul
const liWidth = 120
const space = 6
const size = this.info.pics.length
ul.style.width = (liWidth + space) * size - space + 'px'
}
},
components: {
Star
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../../common/stylus/mixins.styl"
.shop-info
position: absolute
top: 195px
bottom: 0
left: 0
width: 100%
background: #fff;
overflow: hidden
.section
padding 16px 14px 14px
font-size 16px
background-color #fff
color #666
border-bottom 1px solid #eee
position relative
.section-title
color #000
font-weight 700
line-height 16px
> .iconfont
float right
color #ccc
.delivery
margin-top 16px
font-size 13px
line-height 18px
.delivery-icon
width 55px
font-size 11px
margin-right 10px
display inline-block
text-align center
color #fff
background-color #0097ff
padding 1px 0
border-radius 4px
.delivery-money
margin-top 5px
.activity
margin-top 16px
.activity-item
margin-bottom 12px
display flex
font-size 13px
align-items center
&.activity-green
.content-tag
background-color rgb(112, 188, 70)
&.activity-red
.content-tag
background-color rgb(240, 115, 115)
&.activity-orange
.content-tag
background-color: rgb(241, 136, 79)
.content-tag
display inline-block
border-radius 2px
width 36px
height: 18px
margin-right 10px
color #fff
font-style normal
position relative
.mini-tag
position absolute
left 0
top 0
right -100%
bottom -100%
font-size 24px
transform scale(.5)
transform-origin 0 0
display flex
align-items center
justify-content center
.pic-wrapper
width: 100%
overflow: hidden
white-space: nowrap
margin-top 16px
.pic-list
font-size: 0
.pic-item
display: inline-block
margin-right: 6px
width: 120px
height: 90px
&:last-child
margin: 0
.detail
margin-bottom -16px
> li
display flex
justify-content space-between
align-items center
margin-right -10px
padding 16px 12px 16px 0
line-height 16px
bottom-border-1px(#ddd)
font-size 13px
> .bold
font-weight 700
color #333
&:last-child
border-none()
.split
width: 100%
height: 16px
border-top: 1px solid rgba(7, 17, 27, 0.1)
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
background: #f3f5f7
</style>
aaa
月售 671 单
20 元起送 / 距离 1058.2 公里
aaa
月售 671 单
20 元起送 / 距离 1058.2 公里
<script>
import HeaderTop from '../../components/HeaderTop/HeaderTop.vue'
export default {
components: {
HeaderTop
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
@import "../../common/stylus/mixins.styl"
.search //搜索
width 100%
height 100%
.header //头部公共 css
background-color #02a774
position fixed
z-index 100
left 0
top 0
width 100%
height 45px
.header_search
position absolute
left 15px
top 50%
transform translateY(-50%)
width 10%
height 50%
.iconfont
font-size 22px
color #fff
.header_title
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
width 30%
color #fff
font-size 22px
text-align center
.search_form
clearFix()
margin-top 45px
background-color #fff
padding 12px 8px
input
height 35px
padding 0 4px
border-radius 2px
font-weight bold
outline none
&.search_input
float left
width 79%
border 4px solid #f2f2f2
font-size 14px
color #333
background-color #f2f2f2
&.search_submit
float right
width 18%
border 4px solid #02a774
font-size 16px
color #fff
background-color #02a774
.list
.list_container
background-color: #fff;
.list_li
display: flex;
justify-content: center;
padding: 10px
border-bottom: 1px solid $bc;
.item_left
margin-right: 10px
.restaurant_img
width 50px
height 50px
display block
.item_right
font-size 12px
flex 1
.item_right_text
p
line-height 12px
margin-bottom 6px
&:last-child
margin-bottom 0
.search_none
margin: 0 auto
color: #333
background-color: #fff
text-align: center
margin-top: 0.125rem
</style>