一,地点详情页
product.vue组件,点击h3标题,跳转到对应地点的详情detail路径
<template> <dl class="s-item"> <dt> <img :src="meta.img" alt="商品图片"> </dt> <dd> <h3><nuxt-link :to="{path:'detail',query:{keyword:meta.name,type:meta.module}}">{{ meta.name }}</nuxt-link></h3> <el-rate v-model="meta.rate" :colors="['#ff9900', '#ff9900', '#FF9900']" disabled/> <span v-if="meta.rate>4" class="s-item-comment">很好</span><span v-else-if="meta.rate>3" class="s-item-comment">一般</span><span v-else class="s-item-comment">很差</span> <span class="s-item-value">{{ meta.rate }}分</span> <span class="s-item-comment-total">{{ meta.comment }}人评论</span> <p> <span class="s-item-type">{{ meta.type }}</span> <span class="s-item-addr">{{ meta.addr }}</span> </p> <p> <em class="s-item-price">¥{{ meta.price }}起</em> <b>{{ meta.status }}</b> </p> <ul> <!-- <li> <span class="detail-type">门票</span>{{meta.ticket}} </li> <li> <span class="detail-type">跟团</span>{{meta.group}} </li> --> <li v-if="meta.scene&&meta.scene.length"> <span class="detail-type">景酒</span>{{ meta.scene }} </li> <li v-else> <span class="detail-type">景酒</span>暂无描述 </li> </ul> </dd> </dl> </template> <script> export default { props: { meta: { type:Object, default(){ return {} } } } } </script>
pages-->新建detail.vue,引入
crumbs.vue面包屑组件,
summary.vue地点详情,
list.vue,商家团购和优惠
<template> <div class="page-detail"> <el-row> <el-col :span="24"> <crumbs :keyword="keyword" :type="type"/> </el-col> </el-row> <el-row> <el-col :span="24"> <summa :meta="product"/> </el-col> </el-row> <el-row class="m-title"> <el-col :span="24"> <h3>商家团购及优惠</h3> </el-col> </el-row> <el-row v-if="canOrder || !login"> <el-col :span="24"> <!-- 登录状态结构 --> <list v-if="login" :list="list"/> <!-- 未登录状态结构 --> <div v-else class="deal-need-login"> <img src="//p0.meituan.net/codeman/56a7d5abcb5ce3d90fc91195e5b5856911194.png" alt="登录查看"> <span>请登录后查看详细团购优惠</span> <el-button type="primary" round> <a href="/login">立即登录</a> </el-button> </div> </el-col> </el-row> </div> </template> <script> import Crumbs from '@/components/detail/crumbs.vue'; import Summa from '@/components/detail/summary.vue' import List from '@/components/detail/list.vue' export default { components:{ Crumbs, Summa, List }, computed:{ canOrder:function(){ // 过滤图片数据,有的数据图片为空 return this.list.filter(item=>item.photos.length).length } }, // 通过ssr获取数据 async asyncData(ctx){ let {keyword,type}=ctx.query; let {status,data:{product,more:list,login}}=await ctx.$axios.get('/search/products',{ params:{ keyword, type, city:ctx.store.state.geo.position.city } }) if(status===200){ return { keyword, product, type, list, login } }else{ return { keyword, product:{}, type, list:[], login:false } } } } </script> <style lang="scss"> @import "@/assets/css/detail/index.scss"; </style>
crumbs.vue面包屑组件,
<template> <div class="m-crumbs"> <el-breadcrumb separator=">"> <el-breadcrumb-item :to="{ path: '/' }">{{ $store.state.geo.position.city.replace('市','') }}美团</el-breadcrumb-item> <el-breadcrumb-item :to="{ path: '/' }">{{ $store.state.geo.position.city.replace('市','') }}{{ type }}</el-breadcrumb-item> <el-breadcrumb-item><a href="/">{{ $store.state.geo.position.city.replace('市','') }}{{ decodeURIComponent(keyword) }}</a></el-breadcrumb-item> </el-breadcrumb> </div> </template> <script> export default { props: { keyword: { type:String, default:'' }, type: { type:String, default:'' } } } </script>
summary.vue地点详情,
el-rate评分组件,el-carousel走马灯组件,element-ui
<template> <dl class="m-sum-card"> <dt> <h1>{{ meta.name }}</h1> <el-rate v-model="rate" disabled /> <span>{{ Number(meta.biz_ext.rating)||rate }}分</span> <span>人均¥{{ Number(meta.biz_ext.cost) }}</span> <ul> <li @click="openMap(meta.location)">地址:{{ meta.address }}</li> <li>电话:{{ meta.tel }}</li> </ul> </dt> <dd> <el-carousel height="214px" indicator-position="none"> <el-carousel-item v-for="(item,idx) in meta.photos" :key="idx"> <h3><img :src="item.url" alt="item.title" width="100%" height="100%"></h3> </el-carousel-item> </el-carousel> </dd> </dl> </template> <script> export default { props: { meta: { type:Object, default:()=>{ return {} } } }, data() { return { sale: 70 + Math.floor(Math.random() * 300) } }, computed: { rate: function () { return Number(this.meta.biz_ext.rating) || Math.floor(Math.random() * 5) } }, methods: { openMap: function (location) { } } } </script>
list.vue,商家团购和优惠
<template lang="html"> <div class="m-detail-list"> <ul> <li>{{ list.filter(item=>item.photos.length).length }}款套餐</li> <item v-for="(item,idx) in list" :key="idx" :meta="item" /> </ul> </div> </template> <script> import Item from './item.vue' export default { components: { Item }, props: { list: { type:Array, default:()=>{ return [] } } }, } </script>
item.vue组件
<template> <li v-if="meta.photos.length" class="m-detail-item"> <dl class="section"> <dd> <img :src="meta.photos[0].url" :alt="meta.photos[0].title"> </dd> <dd> <h4>{{ meta.name }}</h4> <p> <span v-if="meta.biz_ext&&meta.biz_ext.ticket_ordering">剩余:{{ Number(meta.biz_ext.ticket_ordering) }}</span> <span v-if="meta.deadline">截止日期:{{ meta.deadline }}</span> </p> <p> <span class="price">{{ Number(meta.biz_ext.cost) }}</span> <sub>门店价{{ Number(meta.biz_ext.cost) }}</sub> </p> </dd> <dd> <el-button type="warning" round @click="createCart">立即抢购</el-button> </dd> </dl> </li> </template> <script> export default { props: { meta: { type: Object, default: () => { return {} } } }, methods: { createCart: async function () { let self = this; let { status, data: { code, id } } = await this.$axios.post('/cart/create', { params: { id: Math.random().toString().slice(3, 9), detail: { name: self.meta.name, price: self.meta.biz_ext.cost, imgs: self.meta.photos } } }) if(status===200&&code===0){ // 跳转到购物车页面 window.location.href=`/cart/?id=${id}` }else{ console.log('error') } } } } </script> <style lang="scss"> </style>
二,购物车功能
1.在地点详情页detail中,点击立即请购按钮,跳转到购物车页面
pages-->cart.vue购物车,引入list组件
<template> <div class="page-cart"> <el-row> <el-col v-if="cart.length" :span="24" class="m-cart"> <list :cart-data="cart"/> <p> 应付金额:<em class="money">¥{{ total }}</em> </p> <div class="post"> <el-button type="primary" @click="submit">提交订单</el-button> </div> </el-col> <el-col v-else class="empty">购物车为空</el-col> </el-row> </div> </template> <script> import List from '@/components/cart/list.vue' export default { components:{ List }, data(){ return { cart:[] } }, computed:{ total(){ let total=0; this.cart.forEach(item=>{ total+=item.price*item.count }) return total } }, methods:{ submit: async function(){ let {status,data:{code,id}}=await this.$axios.post('/order/createOrder',{ count:this.cart[0].count, price:this.cart[0].price, id:this.cartNo }) if(status==200&&code===0){ this.$alert(`恭喜您,已成功下单,订单号:${id}`,'下单成功',{ confirmButtonText:'确定', callback:action=>{
//跳转到订单页面 location.href='/order' } }) } } }, // 通过ssr获取数据 async asyncData(ctx){ let {status,data:{code,data:{name,price}}}=await ctx.$axios.post('/cart/getCart',{ id:ctx.query.id }) if(status===200&&code===0&&name){ return { cart:[{ name, price, count:1 }], cartNo:ctx.query.id } } } } </script> <style lang="scss"> @import "@/assets/css/cart/index.scss"; </style>
list.vue组件,el-input-number,计数器组件
<template> <el-table :data="cartData" style=" 980px"> <el-table-column prop="name" label="项目" width="532"/> <el-table-column prop="price" label="单价" width="132"/> <el-table-column label="数量" width="212"> <template slot-scope="scope"> <el-input-number v-model="scope.row.count" :min="0"/> </template> </el-table-column> <el-table-column label="总价"> <template slot-scope="scope"> <div class=""> {{ scope.row.price*scope.row.count }} </div> </template> </el-table-column> </el-table> </template> <script> export default { props:{ cartData:{ type:Array, default:()=>{ return [] } } } } </script>
三,在订单页面功能
1.在购物车页,点击提交订单按钮,跳转到订单页面