高仿美团微信小程序_微信小程序原生仿美团点餐-程序员宅基地

技术标签: Uniapp  小程序  

框架解析

在这里插入图片描述

项目简介

1、主程序入口配置

import App from './App'
import { openWin, redirectTo, backBeaforWin, Ajax } from './utils/common'
import store from './utils/store'
import './css/common.css'
import './css/iconfont.css'

Vue.config.productionTip = false
App.mpType = 'app'
// 把通用方法挂载到Vue原型上
Vue.prototype.$openWin = openWin
Vue.prototype.$redirectTo = redirectTo
Vue.prototype.$backBeaforWin = backBeaforWin
Vue.prototype.$ajax = Ajax
// 把store挂载到Vue原型上
Vue.prototype.$store = store

const app = new Vue(App)
app.$mount()

我们在项目入口里引入公共css、公共方法、以及store,并将公共方法挂载到Vue的原型上

      backgroundTextStyle: 'light',
      navigationBarBackgroundColor: '#fff',
      navigationBarTitleText: '高仿美团',
      navigationBarTextStyle: 'black',
      // enablePullDownRefresh: true
    },
    tabBar: {
      borderStyle: 'white',
      backgroundColor: '#fff',
      selectedColor: '#06c1ae',
      color: '#666',
      list: [{
        pagePath: "pages/index/main",
        iconPath: 'static/images/tab1.png',
        selectedIconPath: 'static/images/tab1-s.png',
        text: "首页"
      },{
        pagePath: "pages/orderList/main",
        selectedIconPath: 'static/images/tab2-s.png',
        iconPath: 'static/images/tab2.png',
        text: "订单"
      },{
        pagePath: "pages/self/main",
        selectedIconPath: 'static/images/tab3-s.png',
        iconPath: 'static/images/tab3.png',
        text: "我的"
      }]
    }

根据小程序app.json的配置,我们配置好所有页page、window以及tabBar

2、首页页面

首页有轮播图,图标九宫格,猜你喜欢的商品列表,还有当前城市和搜索面板,其分别是选择城市页面和搜索页面页面的入口

首页页面的页面布局代码为

  <div class="container ub-box ub-col">
    <dl class="ub-box ub-ver z-padding-v-10-px" style="background:#fff;">
      <dd @click.stop="$openWin('/pages/citySelect/main')" class="z-padding-h-10-px ub-box ub-ver">
        <span class="z-font-size-14 z-color-666 z-margin-right-3-px">{
   {curCity}}</span>
         <i class="iconfont icon-xiangxiazhankai z-color-666 z-font-size-16"></i>
      </dd>
      <dd class="ub-flex-1 ub-box ub-ver">
        <div @click.stop="$openWin('/pages/search/main')" class="search ub-box ub-ver-v z-width-90-percent z-box-sizing-border">
          <i class="iconfont icon-sousuo z-color-666 z-font-size-16"></i>
          <span class="z-font-size-14 z-color-999 z-margin-left-8-px">请输入商家名、品类或者商圈...</span>
        </div>
      </dd>
    </dl>
    <scroll-view scroll-y style="height: calc(100vh - 50px);" scroll-top="0">
      <!--轮播图-->
      <div class="ub-box ub-ver z-bg-color-fff">
        <swiper class="swiper" indicator-dots="false" autoplay="false" interval="5000" duration="500">
          <block v-for="(item, idx) in imgUrls" :key="idx">
            <swiper-item>
              <image :src="item" class="z-width-100-percent" mode="widthFix"/>
            </swiper-item>
          </block>
        </swiper>
      </div>
      <!--图标九宫格入口-->
      <dl class="ub-box ub-wrap z-padding-v-5-px" style="background:#fff">
        <div class="icon-item ub-box ub-col ub-ver" :key="key" v-for="(idx, key) in iconMap">
          <dd @click.stop="$openWin('/pages/error/main')" class="icon ub-box ub-ver iconfont" :class="key" :style="{background: iconMap[key]['bk']}"></dd>
          <span class="z-padding-v-8-px z-font-size-12 z-color-333">{
   {iconMap[key]['title']}}</span> 
        </div>
      </dl>
      <!--广告-->
      <dl class="ub-box ub-wrap z-margin-top-6-px z-padding-v-5-px" style="background:#fff">
        <dd @click.stop="$openWin('/pages/error/main')" class="adv ub-flex-1 z-box-sizing-border ub-box ub-ver ub-col">
          <span class="z-font-size-14 z-lineHeight-36" style="color:#55a40f">我们约吧</span>
          <span class="z-font-size-12 z-color-666">恋人家人好朋友</span>
          <img class="z-img-cover" src="/static/images/index1.png">
        </dd>
        <dd @click.stop="$openWin('/pages/error/main')" class="adv ub-flex-1 z-box-sizing-border z-padding-v-5-px ub-box ub-ver ub-col">
          <span class="z-font-size-14 z-lineHeight-36" style="color:#ff3f0d">低价超值</span>
          <span class="z-font-size-12 z-color-666">十元惠生活</span>
          <img class="z-img-cover" src="/static/images/index2.png">
        </dd>
        <dd @click.stop="$openWin('/pages/error/main')" class="adv ub-flex-1 z-box-sizing-border z-padding-v-5-px ub-box ub-ver ub-col">
          <span class="z-font-size-14 z-lineHeight-36" style="color:#f742a0">午后时光</span>
          <span class="z-font-size-12 z-color-666">懒懒下午茶</span>
          <img class="z-img-cover" src="/static/images/index3.png">
        </dd>
      </dl>
      <!--猜你喜欢,商品列表-->
      <dl class="ub-box ub-col z-margin-top-6-px z-padding-all-8-px" style="background:#fff">
        <p class="z-width-100-percent ub-box ub-ver" style="border-bottom:1px solid #eee">
          <span class="z-font-size-12 z-color-888 z-lineHeight-36">—猜你喜欢—</span>
        </p>
        <dd class="ub-box ub-col">
          <good v-for="(val, idx) in 7" :key="idx" :isLast="idx===6"></good>
        </dd>
      </dl>
    </scroll-view>
  </div>
</template>
<script>
  import good from "../../components/good.vue"
  export default {
    components: {good},
    computed: {
      curCity () {
        return this.$store.state.curCity
      }
    },
    data () {
      return {
        imgUrls: [
          'http://p1.meituan.net/codeman/826a5ed09dab49af658c34624d75491861404.jpg',
          'http://p0.meituan.net/codeman/a97baf515235f4c5a2b1323a741e577185048.jpg',
          'http://p0.meituan.net/codeman/daa73310c9e57454dc97f0146640fd9f69772.jpg'
        ],
        iconMap: {
          'icon-caigou': {title: '美食', bk: '#EF8B3E'}, 
          'icon-shangpin': {title: '猫眼电影', bk: '#E4463B'},
          'icon-touchengkongyun': {title: '酒店住宿', bk: '#8B67E5'},
          'icon-daohang': {title: '休闲娱乐', bk: '#5DC7B0'},
          'icon-zitigui': {title: '外卖', bk: '#F3AE42'},
          'icon-jiesuan': {title: 'KTV', bk: '#5DC1A9'},
          '.icon-jijianfasong': {title: '丽人', bk: '#EC5B6E'},
          'icon-shoucang': {title: '景点门票', bk: '#5CA2F2'},
          'icon-baobiao': {title: '火车票', bk: '#FD9D21'},
          'icon-pifuzhuti': {title: '民宿', bk: '#BED300'},
        },
      }
    },
    methods: {
      async initAjax() {
        let ret = await this.$ajax({url: 'https://devapi.ynshuke.com/v1/banners'})
        console.log(ret)
      }
    },
    mounted() {
      // this.initAjax()
    },
    onPullDownRefresh() {
      console.log('onPullDownRefresh');
      setTimeout(() => {wx.stopPullDownRefresh()}, 600)
    }
  }
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#e8e8e8;}
  .search{background: #f5f5f5;border-radius: 12px;padding: 5px 10px}
  .swiper{height: 120px;width: calc(100% - 16px)}
  .icon-item{width:20%;padding: 10px 13px 0 13px;box-sizing: border-box;}
  .icon{width: 38px;height: 38px;border-radius: 50%;color: #fff;font-size: 24px}
  .adv{border-right: 2px solid #eee}
  .adv img{width: 50px;height: 50px}
  .good{border-bottom: 1px solid #DDD8CE}
  .good img{width: 80px;height: 80px}
</style>

其中我们提取封装出商品卡片组件good

  <div @click.stop="gotoDetail(good.goodId)" class="card ub-box z-padding-v-10-px" :class="{'z-border-bottom-1-eee':isLast==false}">
      <img :src="good.img" class="z-img-cover">
      <div class="z-padding-h-10-px ub-flex-1 ub-box ub-col">
        <p class="ub-flex-1 ub-box ub-ver ub-between">
          <span class="z-width-80-percent z-font-size-15 z-lineHeight-26 z-lines-1-overflow-hidden z-font-weight-bold">{
   {good.mainTitle}}</span>
          <span class="ub-flex-1 z-textAlign-right z-font-size-12 z-color-888">{
   {good.distance}}km</span>
        </p>
        <p class="z-font-size-12 z-color-666 z-lineHeight-20">{
   {good.subTitle}}</p>
        <p class="ub-flex-1 ub-box ub-ver ub-between ub-flex-end">
          <span class="z-font-size-16" style="color:#06c1ae">{
   {good.price}}元</span>
          <span class="z-font-size-12 z-color-888">已售{
   {good.sales}}</span>
        </p>
      </div>
  </div>
</template>
<script>
  export default {
  	props: ['curGood', 'isLast'],
  	data () {
      	return {
      		good: {
	        	goodId: '100',
    				img: 'http://p0.meituan.net/200.0/deal/522fd16a9b25479496188b59476d1b941062402.jpg@206_0_828_828a%7C267h_267w_2e_90Q',
    				mainTitle: '索菲特大酒店锦厨国际餐厅自助餐',
    				subTitle: '单人自助晚餐',
    				distance: '1.7',
    				price: '308',
    				sales: '42739',
	        },
      	}
   	},
   	methods: {
   		gotoDetail(id) {
        wx.navigateTo({url: '/pages/goodDetail/main'})
      }
   	}
  }
</script>
<style scoped>
  .card img{width: 80px;height: 80px}
</style>

注意我们注入store中的当前城市变量,让其不被跳转影响

首页预览效果如下:

image.png

3、城市选择页面

城市选择页面有当前/最近访问城市、热门城市、根据首字母展示所有城市,还有右侧固定住的26个首字母作为点击事件,可以滑动到相应的首字母下的城市列表

我们封装出city组件,其页面布局代码为

	<div class="z-width-100-percent">
    <scroll-view scroll-y style="height:calc(100vh);" scroll-top="0" :scroll-into-view=currView>
      <dl class="ub-box ub-col">
        <dd class="z-width-100-percent z-margin-bottom-5-px z-bg-color-fff ub-box ub-ver">
          <div class="search ub-box ub-ver-v">
            <i class="iconfont icon-sousuo z-color-666 z-font-size-16"></i>
            <input class="ub-flex-1 z-font-size-14 z-color-666 z-padding-v-5-px z-margin-left-8-px" placeholder="城市/拼音"/>
          </div>
        </dd>
        <dd class="z-width-100-percent z-bg-color-fff ub-box z-border-bottom-1-eee">
          <span id="cc" class="z-font-size-14 z-font-weight-bold z-color-333 z-padding-all-8-px">当前:昆明</span>
        </dd>
        <dd class="z-width-100-percent z-bg-color-fff ub-box">
          <span class="z-font-size-14 z-color-333 z-font-weight-bold z-padding-all-8-px">定位/最近访问</span>
        </dd>
        <dd class="z-width-100-percent z-bg-color-fff ub-box">
          <ul class="ub-box ub-wrap z-padding-all-8-px">
            <li @click.stop="clickCity(city)" v-for="(city, idx) in visitCityList" :key="idx" class="hotcity z-font-size-14 z-color-333">{
   {city.name}}</li>
          </ul>
        </dd>
        <dd class="z-width-100-percent z-bg-color-fff ub-box">
          <span class="z-font-size-14 z-color-333 z-font-weight-bold z-padding-all-8-px">热门城市</span>
        </dd>
        <dd class="z-width-100-percent z-bg-color-fff ub-box">
          <ul class="ub-box ub-wrap z-padding-all-8-px">
            <li @click.stop="clickCity(city)" v-for="(city, idx) in hotCityList" :key="idx" class="hotcity z-font-size-14 z-color-333">{
   {city.name}}</li>
          </ul>
        </dd>
        <dd class="z-width-100-percent z-bg-color-fff ub-box">
          <span class="z-font-size-14 z-color-333 z-font-weight-bold z-padding-all-8-px">所有城市</span>
        </dd>
        <dd class="ub-box ub-col">
          <div v-for="(val, idx) in cityList" :key="idx" class="z-width-100-percent z-bg-color-fff ub-box ub-col">
            <span :id="val.initial" class="ub-flex-1 z-padding-all-8-px z-font-size-14 z-color-888 codeBK">{
   {val.initial}}</span>
            <ul class="ub-box ub-col">
              <li @click.stop="clickCity(city)" v-for="(city, i) in val.list" :key="i" class="city ub-flex-1 z-font-size-14 z-color-666">{
   {city.name}}</li>
            </ul>
          </div>
        </dd>
      </dl>
    </scroll-view>
    <!--fixed部分-->
    <dl class="fixList ub-box ub-col ub-ver-v">
      <dt class="z-font-size-12 z-margin-bottom-3-px" style="color:#06c1ae">最近热门</dt>
      <dd @click.stop="clickCode(val)" v-for="(val, idx) in cityList" :key="idx" class="z-font-size-12" style="margin-bottom:2px;color:#06c1ae;padding:0 50px;">{
   {val.initial}}</dd>
    </dl>
	</div>
</template>
<script>
  import cityData from "../utils/cityData.js"
  export default {
    data () {
      return {
        currView: '',
        visitCityList: [
          {zip: "010", name: "北京"},
          {zip: "021", name: "上海"},
        ],
        hotCityList: [
          {zip: "010", name: "北京"},
          {zip: "021", name: "上海"},
          {zip: "020", name: "广州"},
          {zip: "0755", name: "深圳"},
          {zip: "022", name: "天津"},
          {zip: "028", name: "成都"},
          {zip: "0571", name: "杭州"},
          {zip: "023", name: "重庆"},
          {zip: "025", name: "南京"},
        ],
        cityList: [],
        selectCity: {},
      }
    },
    onLoad() {
      this.initCityList()
      this.currView = ''
    },
    methods: {
      initCityList() {
        this.cityList = cityData
      },
      clickCode(obj){
        if (obj.list.length < 1) return
        this.currView = obj.initial
      },
      clickCity(city) {
        this.$emit('cityService', city.name)
      }
    },
  }
</script>
<style scoped>
  .search{background: #f5f5f5;width: 90%;border-radius: 15px;padding: 0 10px}
  .codeBK{background: #f5f5f5}
  .hotcity{border:1px solid #f5f5f5;padding: 6px 12px;margin: 0 8px 8px 0}
  .city{padding: 10px 8px;border-bottom: 1px solid #f5f5f5}
  .fixList{position: fixed;right:5px;top: 12%;z-index: 10;width: 30px;background: transparent;}
</style>

我们引入cityData,并在点击任意城市的时候emit给父组件(即城市选择页面)

对于点击首字母滑动页面到相应首字母对应城市的位置的处理,由于小程序没有任何dom,我们不能使用锚点或者window.scrollTo,但是我们可以利用原生小程序提供的scroll-view中scroll-into-view属性来滚动到相应位置,为此我们只需要用Vue来托管scroll-into-view变量currView即可

最终城市选择页面在真机上显示如下

image.png

4、搜索页面

搜索页面有搜索输入框,猜你想找和历史搜索的面板 ,对于动态监听到输入的搜索关键词,以滚动列表的形式展示符合搜索关键词的结果集合,所以猜你想找和历史搜索的面板,与搜索结果列表为互斥关系

搜索页面的页面布局代码为

  <div class="container">
    <dl class="ub-box ub-col">
      <dd class="z-width-100-percent z-padding-all-8-px z-bg-color-fff ub-box ub-ver z-box-sizing-border" style="80px;">
        <div class="ub-flex-1 search ub-box ub-ver-v">
          <i class="iconfont icon-sousuo z-color-666 z-font-size-16"></i>
          <input @input="doInput" @confirm="doSearch" class="ub-flex-1 z-font-size-14 z-color-666 z-padding-v-5-px z-margin-left-8-px" placeholder="保利国际影院"/>
        </div>
        <span @click.stop="$backBeaforWin()" class="z-font-size-13 z-margin-left-8-px" style="color:#06c1ae">取消</span>
      </dd>
      <!--搜索值不为空的时候,显示搜索列表-->
      <div v-if="searchVal.length>0" class="ub-box ub-col" style="padding:8px 8px 0 8px">
        <scroll-view scroll-y style="height: calc(100vh - 80px)" scroll-top="0">
          <ul class="ub-box ub-col">
            <li @click.stop="clickSearchItem(val)" v-if="currSearchList.length>0" class="search-item ub-box ub-ver z-box-sizing-border" v-for="(val, i) in currSearchList" :key="i">
              <i class="iconfont icon-sousuo z-color-999 z-font-size-16 z-margin-right-10-px"></i>
              <p class="ub-flex-1 z-color-333 z-font-size-14">{
   {val.val}}</p>
              <span class="z-font-size-12 z-color-999">约{
   {val.num}}个结果</span>
            </li>
            <li @click.stop="clickSearchItem(searchVal)" v-if="currSearchList.length===0" class="search-item ub-box ub-ver z-box-sizing-border">
              <i class="iconfont icon-sousuo z-color-999 z-font-size-16 z-margin-right-10-px"></i>
              <p class="ub-flex-1 z-color-333 z-font-size-14">搜索"{
   {searchVal}}"</p>
              <i class="iconfont icon-xiayiyeqianjinchakangengduo z-color-999 z-font-size-16"></i>
            </li>
          </ul>
         </scroll-view>
      </div>
      <!--搜索值为空的时候,显示猜你想找和历史搜索-->
      <div v-if="searchVal.length===0" class="ub-box ub-col">
        <dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box">
          <p class="z-font-size-14 z-color-888">猜你想找</p>
        </dd>
        <dd class="z-margin-h-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box">
          <ul class="ub-box ub-wrap">
            <li @click.stop="clickSearchItem(val)" v-for="(val, idx) in guess" :key="idx" class="item z-font-size-13 z-color-333">{
   {val.name}}</li>
          </ul>
        </dd>
        <dd class="z-margin-h-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between">
          <p class="z-font-size-14 z-color-888">历史搜索</p>
          <i class="iconfont icon-juqianshou z-color-999 z-font-size-16"></i>
        </dd>
        <dd class="z-margin-h-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box">
          <ul class="ub-box ub-wrap">
            <li @click.stop="clickSearchItem(val)" v-for="(val, idx) in history" :key="idx" class="item z-font-size-13 z-color-333">{
   {val.name}}</li>
          </ul>
        </dd>
      </div>
    </dl>
  </div>
</template>
<script>
  export default {
    data () {
      return {
        searchVal: '',
        // 测试搜索结果集
        searchAllList: [
          {id: '1', val: '我呀便当', num: '7'},
          {id: '2', val: '我家黑鱼馆', num: '5'},
          {id: '3', val: '我家酸菜鱼', num: '3'},
          {id: '4', val: '我家厨房', num: '1'},
          {id: '5', val: '我家吃铺', num: '1'},
          {id: '6', val: '我的店', num: '2'},
          {id: '7', val: '我爱水果', num: '3'},
          {id: '8', val: '我家美蛙鱼头', num: '1'},
          {id: '9', val: '我家黑鱼', num: '2'},
          {id: '10', val: '我的巧克力', num: '1'},
          {id: '11', val: '我的公寓', num: '1'},
          {id: '12', val: '我香我逸西餐厅', num: '1'},
        ],
        currSearchList: [], // 当前根据搜索关键词搜索到的列表
        guess: [
          {goodId: '1', name: '北京欢乐谷'}, {goodId: '2', name: '故宫博物院'},
          {goodId: '3', name: '北京野生动物园'}, {goodId: '4', name: '古北水镇'},
          {goodId: '5', name: '八达岭长城'}, {goodId: '6', name: '北京海洋馆'},
        ],
        history: [
          {goodId: '6', name: '北京海洋馆'},
          {goodId: '3', name: '北京野生动物园'},
        ]
      }
    },
    methods: {
      doInput(e) {
        this.searchVal = e.mp.detail.value
        this.filterList()
      },
      doSearch(e) {
        this.searchVal = e.mp.detail.value
      },
      filterList() {
        this.currSearchList = this.searchAllList.filter(item => {
          if (item.val.indexOf(this.searchVal) >= 0) return item
        })
      },
      clickSearchItem(val) {
        this.$redirectTo('/pages/error/main')
      },
    },
    mounted() {
      this.searchVal = ''
      this.currSearchList = JSON.parse(JSON.stringify(this.searchAllList))
    },
    onShow() {
      wx.setNavigationBarTitle({title: '搜索'})
    }
  }
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#fff}
  .search{background: #f5f5f5;border-radius: 15px;padding: 0 10px}
  .search-item{border-bottom: 1px solid #eee;padding: 15px 0px;}
  .item{padding: 8px 10px;background: #f5f5f5;border-radius: 3px;margin: 0 8px 8px 0}
</style>

对于模拟搜索动态列表,我们在data里定义搜索总集合、当前搜索关键词和根据当前搜索关键词匹配到的结果列表

          {id: '1', val: '我呀便当', num: '7'},
          {id: '2', val: '我家黑鱼馆', num: '5'},
          {id: '3', val: '我家酸菜鱼', num: '3'},
          {id: '4', val: '我家厨房', num: '1'},
          {id: '5', val: '我家吃铺', num: '1'},
          {id: '6', val: '我的店', num: '2'},
          {id: '7', val: '我爱水果', num: '3'},
          {id: '8', val: '我家美蛙鱼头', num: '1'},
          {id: '9', val: '我家黑鱼', num: '2'},
          {id: '10', val: '我的巧克力', num: '1'},
          {id: '11', val: '我的公寓', num: '1'},
          {id: '12', val: '我香我逸西餐厅', num: '1'},
        ],

我们需要监听input的输入事件和完成事件,来维护当前搜索关键词和动态过滤符合搜索关键词的结果集

最终搜索页面在真机上显示如下

image.png

5、订单列表页面

订单列表页面比较简单了,只有商品列表的滚动展示

这里为了演示滚动效果,我模拟循环了12次常量数据,订单列表页面的页面布局代码为

  <div class="container ub-box">
    <scroll-view scroll-y style="height:calc(100vh);" scroll-top="0">
      <dl class="z-width-100-percent ub-box ub-col">
       <dd @click.stop="$openWin('/pages/orderDetail/main')" v-for="(val, idx) in 12" :key="idx" class="order z-width-100-percent ub-box z-box-sizing-border">
         <img class="z-img-cover" :src="order.img" />
         <div class="ub-flex-1 z-padding-left-10-px ub-box ub-col">
           <span class="z-font-size-15 z-color-333 z-margin-bottom-3-px z-font-weight-bold">{
   {order.name}}</span>
           <span class="z-font-size-12 z-color-888 z-margin-bottom-3-px">数量:{
   {order.num}}</span>
           <span class="z-font-size-12 z-color-888 z-margin-bottom-3-px">总价:{
   {order.price}}</span>
         </div>
         <span class="z-font-size-14" style="color:#06c1ae">{
   {order.type}}</span>
       </dd>
     </dl>
    </scroll-view>
  </div>
</template>
<script>
  export default {
    data () {
      return {
        order: {
          orderId: '100',
          img: 'http://p0.meituan.net/200.0/deal/522fd16a9b25479496188b59476d1b941062402.jpg@206_0_828_828a%7C267h_267w_2e_90Q',
          name: '索菲特大酒店锦厨国际餐厅自助餐',
          num: '1',
          price: '308',
          type: '待评价'
        }
      }
    },
    methods: {},
    onShow () {
      wx.setNavigationBarTitle({title: '订单列表'})
    }
  }
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#fff}
  .order{border-bottom: 1px solid #f5f5f5;padding: 10px 8px;}
  .order img{width: 55px; height: 55px; border-radius: 3px}
</style>

最终订单列表页面在真机上显示如下

image.png

6、我的页面

我的页面有登录、退出、以及4个入口项,在点击登录后动态获取用户信息,渲染登录按钮为用户的头像、昵称、性别和居住地信息,点击退出按钮后清除用户信息并替换为登录按钮

我的页面的页面布局代码为

  <div class="container ub-box ub-col">
    <dl class="ub-box z-padding-all-10-px" style="background:#fff">
      <dd class="ub-box ub-ver">
         <image :src="userInfo.avatarUrl" class="head-img" mode="aspectFill"></image>
      </dd>
      <dd class="ub-flex-1 z-font-size-18 z-color-333 ub-box ub-ver-v z-padding-h-10-px">
        <button v-if="isLogin===false" class="loginBtn" lang="zh_CN" open-type="getUserInfo" @getuserinfo="onGetUserInfo">登录</button>
        <ul v-if="isLogin===true" class="ub-box z-margin-left-10-px ub-col">
          <li class="z-font-size-16 z-color-333 z-margin-bottom-5-px">{
   {userInfo.nickName}}</li>
          <li class="z-font-size-14 z-color-888">{
   {userInfo.province}} {
   {userInfo.city}} {
   {userInfo.gender}}</li>
        </ul>
      </dd>
      <dd class="z-font-size-18 z-color-333 ub-box ub-ver-v">
        <div @click.stop="exitLogin()" class="exitBtn ub-box ub-ver z-font-size-14">退出</div>
      </dd>
    </dl>
    <dl class="ub-box ub-col z-margin-top-10-px" style="background:#fff;">
      <dd @click.stop="gotoOrderList()" class="z-padding-all-10-px ub-box ub-between" style="border-bottom:1px solid #eee">
        <p class="ub-box ub-ver">
        <i class="iconfont icon-danju" style="color:#06c1ae;font-size:20px"></i>
        <span class="z-font-size-15 z-color-666 z-padding-h-10-px">我的订单</span>
        </p>
        <p class="ub-box ub-ver">
        <i class="iconfont icon-xiayiyeqianjinchakangengduo z-font-size-14 z-color-888"></i>
        </p>
      </dd>
      <dd @click.stop="$openWin('/pages/error/main')" class="z-padding-all-10-px ub-box ub-between" style="border-bottom:1px solid #eee">
        <p class="ub-box ub-ver">
        <i class="iconfont icon-hongbao" style="color:#06c1ae;font-size:20px"></i>
        <span class="z-font-size-15 z-color-666 z-padding-h-10-px">我的卷包</span>
        </p>
        <p class="ub-box ub-ver">
        <i class="iconfont icon-xiayiyeqianjinchakangengduo z-font-size-14 z-color-888"></i>
        </p>
      </dd>
      <dd @click.stop="$openWin('/pages/error/main')" class="z-padding-all-10-px ub-box ub-between" style="border-bottom:1px solid #eee">
        <p class="ub-box ub-ver">
        <i class="iconfont icon-caiwu" style="color:#06c1ae;font-size:20px"></i>
        <span class="z-font-size-15 z-color-666 z-padding-h-10-px">我的抽奖</span>
        </p>
        <p class="ub-box ub-ver">
        <i class="iconfont icon-xiayiyeqianjinchakangengduo z-font-size-14 z-color-888"></i>
        </p>
      </dd>
       <dd @click.stop="clickCall()" class="z-padding-all-10-px ub-box ub-between">
        <p class="ub-box ub-ver">
        <i class="iconfont icon-dianhua" style="color:#06c1ae;font-size:20px"></i>
        <span class="z-font-size-15 z-color-666 z-padding-h-10-px">客服电话:10107888</span>
        </p>
      </dd>
    </dl>
  </div>
</template>
<script>
export default {
  computed: {
    isLogin() {
      return this.$store.state.isLogin
    },
    userInfo () {
      return this.$store.state.userInfo
    }
  },
  data () {
    return {}
  },
  methods: {
    onGetUserInfo (e) {
      this.$store.commit('updateIsLogin', true)
      this.$store.commit('updateUser', e.mp.detail.userInfo)
    },
    exitLogin() {
      this.$store.commit('updateIsLogin', false)
      this.$store.commit('cleanUserInfo')
    },
    gotoOrderList() {
      wx.switchTab({url: '/pages/orderList/main'})
    },
    clickCall() {
      wx.showActionSheet({
        itemList: ['客服电话:10107888'],
        success(res) {
          switch(res.tapIndex) {
            case 0:
              wx.makePhoneCall({phoneNumber: '10107888'})
              break
          }
        }
      })
    }
  },
  onShow () {
    wx.setNavigationBarTitle({title: '我的'})
  }
}
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#e8e8e8;object-fit: cover}
  .head-img{width:70px;height:70px;border-radius:50%;box-shadow:0 0 5px rgba(0,0,0,.2);background:#eee}
  .loginBtn{font-size:14px;color:#fff;padding:0px 20px;margin-left: 10px;background: #ff5722}
  .exitBtn{border: 1px solid #06c1ae;padding:7px 15px;color:#06c1ae;border-radius: 3px}
</style>

我们引入store来在用户点击登录或者退出的时候,动态维护用户登录状态和用户信息

最终我的页面在真机上显示如下

image.png

7、商品详情页面

商品详情页面有商品主图价格信息、映像标签、商家信息、套餐信息、购买须知、部分用户评论和相关商品推荐板块,页面里有两个其它页的入口,分别是提交订单和用户评论列表入口

商品详情页面的页面布局代码为

  <div class="container ub-box ub-col ub-ver">
	<scroll-view scroll-y style="height: 100vh" scroll-top="0">
	  <dl class="ub-box ub-col">
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff">
			<image @click.stop="previewImage([indexImg])" class="z-width-100-percent z-img-cover indexImg" :src="indexImg">
				<div class="indexImg-bk ub-box ub-col">
					<span class="z-font-size-18 z-lineHeight-30 z-color-fff z-box-sizing-border z-padding-h-8-px">{
   {mainTitle}}</span>
					<span class="z-font-size-14 z-color-fff z-box-sizing-border z-padding-h-8-px">{
   {subTitle}}</span>
				</div>
			</image>
		</dd>
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="ub-box ub-ver">
				<span class="z-font-size-24 z-margin-right-5-px" style="color:#06c1ae">¥{
   {nowPrice}}</span>
				<span class="z-font-size-13 z-color-888">门市价:¥{
   {normalPrice}}</span>
			</p>
			<p class="ub-box ub-ver">
				<span @click.stop="$openWin('/pages/submit/main')" class="buyBtn ub-box ub-ver z-font-size-16 z-color-fff">
					立即抢购
				</span>
			</p>
		</dd>
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between">
			<p class="ub-box ub-ver">
				<i class="iconfont icon-xianshikejian z-font-size-18 z-margin-right-5-px" style="color:#06c1ae;"></i>
				<span class="z-font-size-12 z-color-888">过期自动退</span>
			</p>
			<p class="ub-box ub-ver">
				<i class="iconfont icon-yonghu z-font-size-16 z-margin-right-5-px" style="color:#888;"></i>
				<span class="z-font-size-12 z-color-888">已售420</span>
			</p>
		</dd>
		<dd class="z-margin-top-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="ub-box ub-ver">
				<span class="z-font-size-13 z-color-888">
					<star></star>
				</span>
			</p>
			<p @click.stop="$openWin('/pages/comment/main')" class="ub-box ub-ver">
				<span class="z-font-size-13 z-color-888">{
   {commentsNum}}条评论</span>
				<i class="iconfont icon-xiayiyeqianjinchakangengduo z-font-size-12 z-color-888"></i>
			</p>
		</dd>
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff  ub-box ub-wrap" style="padding:12px 8px 8px 8px">
			<span v-for="(val, idx) in labels" :key="idx" class="label z-font-size-13" :class="{'tuijian': val.type==1, 'butuijian': val.type==0}">{
   {val.name}} {
   {val.num}}</span>
		</dd>
		<dd class="z-margin-top-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="z-font-size-14 z-color-888">商家信息</p>
		</dd>	
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between">
			<p class="ub-flex-1 ub-box ub-col" style="border-right: 1px solid #eee">
				<span class="z-font-size-14 z-lineHeight-24 z-color-333">{
   {sellerName}}</span>
				<span class="z-font-size-13 z-color-999">{
   {sellAdress}}</span>
			</p>
			<p @click.stop="clickCall()" class="ub-box ub-ver z-padding-h-8-px">
				<i class="iconfont icon-dianhua z-font-size-20" style="color:#06c1ae"></i>
			</p>
		</dd>
		<dd class="z-margin-top-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="z-font-size-14 z-color-888">套餐</p>
		</dd>	
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="z-font-size-14 z-color-333">{
   {package.packageName}}</p>
			<p class="ub-box">
				<span class="z-font-size-14 z-color-333 z-margin-right-5-px">1位</span>
				<span class="z-font-size-14 z-color-333">¥{
   {normalPrice}}</span>
			</p>
		</dd>
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-ver" style="border-bottom: 1px solid #f5f5f5">
			<p class="z-font-size-14 z-color-888">备注</p>
		</dd>
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-col">
			<ul class="ub-box ub-col">
				<li v-for="(val, idx) in package.notes" :key="idx" class="z-font-size-14 z-color-333 z-box-sizing-border z-lineHeight-24">{
   {val}}</li>
			</ul>
		</dd>
		<dd class="z-margin-top-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="z-font-size-14 z-color-888">购买须知</p>
		</dd>	
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-col">
			<p class="z-font-size-14 z-lineHeight-30" style="color:#f90">有效期</p>
			<p class="z-font-size-14 z-color-888">{
   {purchaseInfo.validityDate}}</p>
			<p class="z-font-size-14 z-lineHeight-30" style="color:#f90">不可用日期</p>
			<p class="z-font-size-14 z-color-888">{
   {purchaseInfo.unavailableDate}}</p>
			<p class="z-font-size-14 z-lineHeight-30" style="color:#f90">使用规则</p>
			<ul class="ub-box ub-col" >
				<li v-for="(val, idx) in purchaseInfo.rules" :key="idx" class="z-font-size-14 z-color-888 z-box-sizing-border z-lineHeight-24">{
   {val}}</li>
			</ul>
		</dd>
		<dd class="z-margin-top-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="ub-box ub-ver">
				<span class="z-font-size-14 z-color-888">
					<star></star>
				</span>
			</p>
			<p @click.stop="$openWin('/pages/comment/main')" class="ub-box ub-ver">
				<span class="z-font-size-14 z-color-888">{
   {commentsNum}}条评论</span>
				<i class="iconfont icon-xiayiyeqianjinchakangengduo z-font-size-12 z-color-888"></i>
			</p>
		</dd>
		<dd class="z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between">
			<ul class="ub-flex-1 ub-box ub-col">
				<li v-for="(val, idx) in comments" :key="idx" class="z-border-bottom-1-eee">
					<comment :comment="val" :isShowLike="false"></comment>
				</li>
			</ul>
		</dd>
		<dd @click.stop="$openWin('/pages/comment/main')" class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-h-8-px ub-box ub-between">
			<p class="z-margin-bottom-8-px ub-box ub-ver">
				<span style="color:#06c1ae" class="z-font-size-14 z-color-888">查看全部用户评价</span>
			</p>
			<p class="ub-box ub-ver">
				<i class="iconfont icon-xiayiyeqianjinchakangengduo z-font-size-13 z-color-888"></i>
			</p>
		</dd>
		<dd class="z-margin-top-8-px z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-between" style="border-bottom: 1px solid #f5f5f5">
			<p class="z-font-size-14 z-color-888">相关推荐</p>
		</dd>
		<dd class="z-width-100-percent z-box-sizing-border z-bg-color-fff z-padding-all-8-px ub-box ub-col">
        	<good v-for="(val, idx) in 2" :key="idx" :isLast="idx==1"></good>
        </dd>								
	  </dl>
	</scroll-view>
  </div>
</template>
<script>
	import good from "../../components/good.vue"
	import star from "../../components/star.vue"
	import comment from "../../components/comment.vue"
	export default {
		components: {good, star, comment},
	  	data () {
			return {
				indexImg: 'http://p0.meituan.net/deal/522fd16a9b25479496188b59476d1b941062402.jpg',
				mainTitle: '索菲特大酒店锦厨国际餐厅自助餐',
				subTitle: '单人自助晚餐',
				nowPrice: '308',
				normalPrice: '398',
				labels: [
					{name: '海鲜棒', num: '202', type: '1'}, 
					{name: '回头客', num: '97', type: '1'},
					{name: '干净卫生', num: '40', type: '1'}, 
					{name: '上菜快', num: '22', type: '1'},
					{name: '不推荐', num: '29', type: '0'},
					{name: '家庭聚餐', num: '13', type: '0'},
					{name: '朋友聚餐', num: '9', type: '0'}, 
					{name: '闺蜜聚会', num: '5', type: '0'},
					{name: '现做现卖', num: '4', type: '0'}, 
					{name: '请客', num: '4', type: '0'},
				],
				sellerName: '索菲特大酒店锦厨国际餐厅自助餐',
				sellAdress: '西山区环城南路777号昆明索菲特大酒店49楼',
				package: {
					packageName: '单人自助晚餐',
					notes: [
						'单人自助晚餐:周一至周四18:00-21:00',
						'餐厅预定入口: https://tableplus.accorplus.com?vc=KweeZeenRestaurantAccorASE1187',
						'锦厨国际餐厅位于昆明索菲特大酒店49楼,能够360度鸟瞰春城美景。',
						'我们为您提供400种以上的餐食自助,全场酒水畅饮,包括葡萄酒、各色软饮及果汁。',
						'更有专属定制化服务:凡周年纪念日/生日当天到店就餐的客人,将免费提供蛋糕一个(此项仅针对提前至少一天进行预约并说明过情况的客人。)',
						'温馨提示:儿童按身高收费,具体是0-110cm儿童免费;110cm-140cm儿童半价;140cm以上的全价。 另:如遇特殊活动时,需根据店里实际情况按实际价格补差价。',
					],
				},
				purchaseInfo: {
					validityDate: '2016.2.5 至 2018.6.14',
					unavailableDate: '周五至周日',
					rules: [
						'提前2天预订,周末及节假日提前2天以上预订。预订电话:0871-68639888转锦厨国际餐厅',
						'锦厨国际餐厅位于昆明索菲特大酒店49楼,能够360度鸟瞰春城美景。',
						'我们为您提供400种以上的餐食自助,全场酒水畅饮,包括葡萄酒、各色软饮及果汁。',
						'更有专属定制化服务:凡周年纪念日/生日当天到店就餐的客人,将免费提供蛋糕一个(此项仅针对提前至少一天进行预约并说明过情况的客人。)',
						'部分菜品因时令原因有所不同,请以店内当日实际供应为准',
						'提供免费WiFi',
						'停车位收费标准:免费停车',
					]
				},
				commentsNum: 6,
				comments: [
					{
						header: 'https://img.meituan.net/avatar/855458f5c24ab19951f382ee99533ad981495.jpg@37w_37h_1e_1c',
						name: 'AqU753874254',
						time: '2018-05-07', 
						star: '4.0',
						say: '菜品很多,强烈推荐龙虾,超级棒!每次来都吃撑!很满意的一家自主餐!生日当天海送了蛋糕、服务员“代玉琳”美女,服务态度超级好,热情,人也长的美美哒,给她一个赞! ', 
						imgs: [
							'http://p0.meituan.net/shaitu/40b07a385f90bca838efa48a911bf491253024.jpg',
							'http://p0.meituan.net/shaitu/f6af829ff902040fb3225643b2775c1f111115.jpg',
							'http://p0.meituan.net/shaitu/e96132da9f76af022d6e521b2265ad70204304.jpg',
							'http://p0.meituan.net/shaitu/307d287b8d55f1d67dab188502a684ec158341.jpg',
						]
					},
					{
						header: 'https://p0.meituan.net/122.74/mmc/35ad1f9253761ea6ff822b5e659f234f3758.png',
						name: 'PPL546030823',
						time: '2018-05-06', 
						star: '4.5',
						say: '环境很好,有昆明的夕阳相伴,谢谢美女服务员代玉琳的热忱服务,度过和朋友悠闲的晚餐时光 #煎鹅肝# ', 
						imgs: [
							'http://p0.meituan.net/400.0/shaitu/bc52b03f7f091d6711b8a1ec024a0e6a83730.jpg',
							'http://p0.meituan.net/400.0/shaitu/053247a6b8ede53824435f23196971d2124167.jpg',
							'http://p0.meituan.net/400.0/shaitu/0783b3f70ab47607593dcba906c7d570147806.jpg',

						]
					},
				],
			}
		},
		methods: {
			previewImage(imgs=[], curIdx=0){
				wx.previewImage({current: imgs[curIdx], urls: imgs})
			},
			clickCall() {
		      wx.showActionSheet({
		        itemList: ['客服电话:10107888'],
		        success(res) {
		          switch(res.tapIndex) {
		            case 0:
		              wx.makePhoneCall({phoneNumber: '10107888'})
		              break
		          }
		        }
		      })
		    },
		},
		onShow() {
    		wx.setNavigationBarTitle({title: this.mainTitle})
  		}
	}
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#e8e8e8}
  .indexImg{height: 170px;position: relative;}
  .indexImg-bk{position: absolute;bottom: 0;left: 0;z-index: 1;width: 100%;height: 30%;background: rgba(0,0,0,.3);padding: 5px 0px}
  .buyBtn{background: #f90;padding: 8px 12px;border-radius:3px}
  .label{border-radius:3px;background: #fff;padding: 3px 5px;margin: 0 5px 5px 0}
  .tuijian{color: #f90;border:1px solid #f90;}
  .butuijian{color: #999;border:1px solid #ddd;}
</style>

这个页面里用到了卡片组件good,打星评分组件star和评论组件comment,good组件首页已经封装好,下面我们封装出star和comment组件

注意:由于小程序没有伪类,为此我们利用absolute来动态渲染星星的颜色

下面是comment组件的布局代码

  <div class="z-width-100-percent ub-box z-padding-v-10-px">
    <div class="z-margin-right-10-px">
      <img class="z-img-cover" :src="comment['header']" style="width:40px;height:40px;border-radius:50%">
    </div>
    <ul class="ub-flex-1 ub-box ub-col">
      <li class="ub-box ub-between z-margin-bottom-3-px">
        <span class="z-font-size-14 z-color-333">{
   {comment.name}}</span>
        <span class="z-font-size-12 z-color-888">{
   {comment.time}}</span>
      </li>
      <li class="ub-box ub-between z-margin-bottom-3-px">
        <star :isShowNum="false" :num="comment.star"></star>
      </li>
      <li class="ub-box z-margin-bottom-8-px">
        <p class="z-font-size-14 z-color-333 z-lineHeight-22">{
   {comment.say}}</p>
      </li>
      <li v-if="comment.imgs.length > 0" class="ub-box z-margin-bottom-8-px">
        <div @click.stop="previewImage(comment.imgs, i)" class="z-margin-right-5-px z-width-25-percent" v-for="(img, i) in comment.imgs" :key="i">
          <img class="z-img-cover" style="width:100%;height:70px;" :src="img">
        </div>
      </li>
      <li v-if="isShowLike" class="ub-box ub-end">
        <div class="like ub-box ub-ver">
          <i class="iconfont icon-xihuan z-font-size-14 z-margin-right-5-px z-color-999"></i>
          <span class="z-font-size-12 z-color-666">赞</span>
        </div>
      </li>
    </ul>
  </div>
</template>
<script>
  import star from "./star.vue"
  export default {
    props: {
      comment: {
        type: Object
      },
      isShowLike: {
        type: Boolean,
        default: true
      },
    },
    components: {star},
    data () {
      return {}
    },
    mounted() {},
    methods: {
      previewImage(imgs=[], curIdx=0){
        wx.previewImage({current: imgs[curIdx], urls: imgs})
      },
    },
  }
</script>
<style scoped>
	.like{border-radius: 10px; padding: 2px 13px;border:1px solid #eee;}
</style>

最终商品详情页面在真机上显示如下

image.png

8、评论列表页面

这个页面是通过商品详情页为入口进入,其评论分为全部、晒图评论、低分评论和最新评论,各个评论的通过swiper滑动切换来更新相应的评论列表

评论列表页面的页面布局为

  <div class="container">
    <!--评论类型tab栏-->
    <dl class="z-width-100-percent ub-box z-box-sizing-border">
      <dd @click.stop="clickTab(idx)" v-for="(val, idx) in tabs" :key="idx" :class="{'on': curIdx==idx}" class="ub-flex-1 ub-box ub-ver swiper-item z-box-sizing-border z-font-size-14 z-color-666 z-padding-v-10-px">{
   {val}}</dd>
    </dl>
    <!--相应评论类型的tab内容-->
    <swiper :current="curIdx" class="swiper-box" duration="300" style="height:calc(100vh - 30px)" @change="bindchange">
      <!--全部评论-->
      <swiper-item item-id="t1">
        <scroll-view scroll-y style="height: calc(100vh - 30px)" scroll-top="0">
          <dl class="z-margin-top-10-px ub-box ub-col z-width-100-percent z-padding-h-10-px z-box-sizing-border">
            <dd v-if="allComments.length > 0" class="z-border-bottom-1-eee" v-for="(val, idx) in allComments" :key="idx">
              <comment :comment="val"></comment>
            </dd>
            <p v-if="allComments.length === 0" class="ub-box ub-ver z-padding-v-10-px">
              <span class="z-font-size-13 z-color-888">暂无评论...</span>
            </p>
          </dl>
        </scroll-view>
      </swiper-item>
      <!--晒图评论-->
      <swiper-item item-id="t2">
        <scroll-view scroll-y style="height: calc(100vh - 30px)" scroll-top="0">
          <dl class="z-margin-top-10-px ub-box ub-col z-width-100-percent z-padding-h-10-px z-box-sizing-border">
            <dd v-if="hasImgComments.length > 0" class="z-border-bottom-1-eee" v-for="(val, idx) in hasImgComments" :key="idx">
              <comment :comment="val"></comment>
            </dd>
            <p v-if="hasImgComments.length === 0" class="ub-box ub-ver z-padding-v-10-px">
              <span class="z-font-size-13 z-color-888">暂无评论...</span>
            </p>
          </dl>
        </scroll-view>
      </swiper-item>
      <!--低分评论-->
      <swiper-item item-id="t3">
         <scroll-view scroll-y style="height: calc(100vh - 30px)" scroll-top="0">
          <dl class="z-margin-top-10-px ub-box ub-col z-width-100-percent z-padding-h-10-px z-box-sizing-border">
            <dd v-if="lowScoreComments.length > 0" class="z-border-bottom-1-eee" v-for="(val, idx) in lowScoreComments" :key="idx">
              <comment :comment="val"></comment>
            </dd>
            <p v-if="lowScoreComments.length === 0" class="ub-box ub-ver z-padding-v-10-px">
              <span class="z-font-size-13 z-color-888">暂无评论...</span>
            </p>
          </dl>
        </scroll-view>
      </swiper-item>
      <!--最近评论-->
      <swiper-item item-id="t4">
        <scroll-view scroll-y style="height: calc(100vh - 30px)" scroll-top="0">
          <dl class="z-margin-top-10-px ub-box ub-col z-width-100-percent z-padding-h-10-px z-box-sizing-border">
            <dd v-if="lastComments.length > 0" class="z-border-bottom-1-eee" v-for="(val, idx) in lastComments" :key="idx">
              <comment :comment="val"></comment>
            </dd>
            <p v-if="lastComments.length === 0" class="ub-box ub-ver z-padding-v-10-px">
              <span class="z-font-size-13 z-color-888">暂无评论...</span>
            </p>
          </dl>
        </scroll-view>
      </swiper-item>
    </swiper>
  </div>
</template>
<script>
  import comment from "../../components/comment.vue"
  export default {
    components: {comment},
    data () {
      return {
        curIdx: 0,
        tabs: [],
        allComments: [
            {
              header: 'https://img.meituan.net/avatar/855458f5c24ab19951f382ee99533ad981495.jpg@37w_37h_1e_1c',
              name: 'AqU753874254',
              time: '2018-05-07', 
              star: '4.0',
              say: '菜品很多,强烈推荐龙虾,超级棒!每次来都吃撑!很满意的一家自主餐!生日当天海送了蛋糕、服务员“代玉琳”美女,服务态度超级好,热情,人也长的美美哒,给她一个赞! ', 
              imgs: [
                'http://p0.meituan.net/shaitu/40b07a385f90bca838efa48a911bf491253024.jpg',
                'http://p0.meituan.net/shaitu/f6af829ff902040fb3225643b2775c1f111115.jpg',
                'http://p0.meituan.net/shaitu/e96132da9f76af022d6e521b2265ad70204304.jpg',
                'http://p0.meituan.net/shaitu/307d287b8d55f1d67dab188502a684ec158341.jpg',
              ]
            },
            {
              header: 'https://p0.meituan.net/122.74/mmc/35ad1f9253761ea6ff822b5e659f234f3758.png',
              name: 'PPL546030823',
              time: '2018-05-06', 
              star: '4.5',
              say: '环境很好,有昆明的夕阳相伴,谢谢美女服务员代玉琳的热忱服务,度过和朋友悠闲的晚餐时光 #煎鹅肝# ', 
              imgs: [
                'http://p0.meituan.net/400.0/shaitu/bc52b03f7f091d6711b8a1ec024a0e6a83730.jpg',
                'http://p0.meituan.net/400.0/shaitu/053247a6b8ede53824435f23196971d2124167.jpg',
                'http://p0.meituan.net/400.0/shaitu/0783b3f70ab47607593dcba906c7d570147806.jpg',
              ]
            },
            {
              header: 'https://img.meituan.net/122.74/avatar/5311913bf65406ba020854e2436c9ca156391.jpg',
              name: 'SWB34889218',
              time: '2018-04-18', 
              star: '5.0',
              say: '每次来都吃的好撑!菜品超级多!肖亚萍和茶宏燕两个小姐姐超级热情,超级体贴!', 
              imgs: []
            },
            {
              header: 'https://p0.meituan.net/122.74/mmc/35ad1f9253761ea6ff822b5e659f234f3758.png',
              name: 'smsaikyo',
              time: '2018-04-13',
              star: '3.8', 
              say: '真的不错呢【口味】【环境】【服务】', 
              imgs: []
            },
            {
              header: 'https://img.meituan.net/122.74/avatar/5e1702cffcb2045e5703569dfec6aa5743059.jpg',
              name: 'Zjx983004122',
              time: '2018-04-12', 
              star: '3.6',
              say: '菜品非常好!环境高大上!如果你爱你的姑娘就带她来索菲特锦厨国际餐厅吧!奥对了我真的很想给服务生李艺鑫六星好评!服务太到位了,像一家人一样!李艺鑫下次因为你的服务而来。', 
              imgs: ['http://p0.meituan.net/400.0/shaitu/290aad74bf18e7cd1409a62d96bd2106178617.jpg']
            },
            {
              header: 'https://p0.meituan.net/122.74/mmc/35ad1f9253761ea6ff822b5e659f234f3758.png',
              name: 'pny1980',
              time: '2018-04-10', 
              star: '1.0',
              say: '菜品一般,团购就不给开发票,投诉到底我就不信了。最搞笑的就是用餐当中房顶漏水!', 
              imgs: []
            },
          ],
          hasImgComments: [],
          lowScoreComments: [],
          lastComments: [],
      }
    },
    methods: {
      bindchange(e) {
        this.curIdx = e.target.current
      },
      clickTab(i) {
        if (this.curIdx === i) return
        this.curIdx = i
      },
      // 比较日期是否在当前日期的recently范围之间
      compareDateToNow(time) {
        const compare = new Date(time.replace(/-/g,'\/')).getTime()
        const recently = 86400000 * 3 // 定义三天之内
        return new Date().getTime() - recently <= compare
      },
      initAllComments(){
        // 晒图评论类型:从全集过滤出有图片的集合
        this.hasImgComments = this.allComments.filter(item => {
          if(item.imgs.length > 0) return item
        })
        // 低分评论类型:从全集过滤出分数小于3的集合
        this.lowScoreComments = this.allComments.filter(item => {
          if((item.star|0) < 3) return item
        })
        // 最新评论类型:从全集过滤出3天之内的集合
        this.lastComments = this.allComments.filter(item => {
          if(this.compareDateToNow(item.time)) return item
        })
        this.curIdx = 0
        this.tabs = new Array(4)
        this.tabs[0] = '全部(' + this.allComments.length + ')'
        this.tabs[1] = '晒图(' + this.hasImgComments.length + ')'
        this.tabs[2] = '低分(' + this.lowScoreComments.length + ')'
        this.tabs[3] = '最新(' + this.lastComments.length + ')'
      },
    },
    mounted() {
      this.initAllComments()
    },
    onShow () {
      wx.setNavigationBarTitle({title: '用户评价'})
    }
  }
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#fff;}
  .swiper-item{border-bottom: 1px solid #ddd;}
  .on{color: #06c1ae;border-bottom: 3px solid #06c1ae;}
  .like{border-radius: 10px; padding: 2px 13px;border:1px solid #eee;}
</style>

为了演示不同类型评论的切换,我们定义好全集评论列表,并过滤计算出不同类型的数组用于渲染不同的列表

最终评论列表页面在真机上显示如下

image.png

9、提交订单页面

这个页面主要有数量的动态增加或者减少,以及价格的动态变化

提交订单页面的页面布局为

  <div class="container ub-box">
   <dl class="ub-box ub-col z-width-100-percent">
    <dd class="item z-width-100-percent ub-box ub-ver ub-between z-box-sizing-border z-bg-color-fff">
      <span class="z-font-size-15 z-color-333 z-font-weight-bold">{
   {formdata.mainTitle}}</span>
      <span class="z-font-size-15 z-color-333 z-font-weight-bold">{
   {formdata.price}}元</span>
    </dd>
    <dd class="item z-width-100-percent ub-box ub-ver ub-between z-box-sizing-border z-bg-color-fff">
      <span class="z-font-size-15 z-color-333 z-font-weight-bold">数量</span>
      <span>
        <counter @counterService="counterService"></counter>
      </span>
    </dd>
    <dd class="item z-width-100-percent ub-box ub-ver ub-between z-box-sizing-border z-bg-color-fff">
      <span class="z-font-size-15 z-color-333 z-font-weight-bold">小计</span>
      <span class="z-font-size-15 z-font-weight-bold" style="color:red">
        ¥{
   {formdata.totalPrice}}
      </span>
    </dd>
    <dd class="item z-margin-top-8-px z-width-100-percent ub-box ub-ver ub-between z-box-sizing-border z-bg-color-fff">
      <p class="ub-box ub-ver">
        <i class="iconfont icon-hongbao z-color-666 z-font-size-18 z-margin-right-5-px" style="color:#f90"></i>
        <span class="z-font-size-15 z-color-333 z-font-weight-bold">抵用券</span>
      </p>
      <p class="ub-box ub-ver">
        <span class="z-font-size-12 z-color-888 z-margin-right-3-px">无可用抵用券</span>
        <i class="iconfont icon-xiayiyeqianjinchakangengduo z-font-size-14 z-color-888"></i>
      </p>
    </dd>
    <dd class="item z-margin-top-8-px z-width-100-percent ub-box ub-ver ub-between z-box-sizing-border z-bg-color-fff">
      <span class="z-font-size-15 z-color-333 z-font-weight-bold">绑定手机号</span>
      <span class="z-font-size-15 z-color-333 z-font-weight-bold">{
   {formdata.phone}}</span>
    </dd>
    <!--fixed部分-->
    <ul class="fixCon ub-box ub-ver ub-between">
      <li class="ub-box ub-ver z-padding-h-10-px">
        <span class="z-font-size-12 z-color-999 z-margin-right-10-px">实付金额</span>
        <span class="z-font-size-18 z-font-weight-bold" style="color:red">¥{
   {formdata.totalPrice}}</span>
      </li>
      <li @click.stop="$openWin('/pages/error/main')" class="sumbitBtn ub-box ub-ver z-font-size-16 z-color-fff">提交订单</li>
    </ul>
   </dl>
  </div>
</template>
<script>
  import counter from "../../components/counter.vue"
  export default {
    components: {counter},
    data () {
      return {
        formdata: {
          goodId: '100',
          mainTitle: '索菲特大酒店锦厨国际餐厅自助餐',
          num: 1,
          price: 308.00,
          totalPrice: 308.00,
          phone: '138****3468',
        }
      }
    },
    methods: {
      counterService(n) {
        this.formdata.num = n
        this.formdata.totalPrice = (this.formdata.price|0) * n
      }
    },
    onShow() {
      wx.setNavigationBarTitle({title: '提交订单'})
    }
  }
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#f5f5f5}
  .item{border-bottom: 1px solid #f5f5f5;padding: 10px 8px;}
  .fixCon{position: fixed;left: 0;bottom: 0;z-index: 10;width: 100%;background: #fff;}
  .sumbitBtn{padding: 15px 35px;background: #06c1ae;box-sizing: border-box;}
</style>

由于数量需要动态增减,我们封装出计数组件counter

counter组件的布局为

	<div class="ub-box ub-ver-v z-width-100-percent">
    <ul class="counter z-width-100-percent ub-box">
      <li @click.stop="changeNum(-1)" class="counter-dis ub-box ub-ver z-font-size-16 z-color-666">-</li>
      <li class="counter-num ub-box ub-ver z-font-size-14 z-color-333">{
   {num}}</li>
      <li @click.stop="changeNum(1)" class="counter-add ub-box ub-ver z-font-size-16">+</li>
    </ul>
	</div>
</template>
<script>
  export default {
    data () {
      return {
      	num: 1,
      }
    },
    mounted() {},
    methods: {
      changeNum(type) {
        if (this.num === 1 && type === -1) return
        this.num += Number(type)
        this.$emit('counterService', this.num)
      }
    },
  }
</script>
<style scoped>
	.counter-dis, .counter-add{padding: 3px 8px;border-top: 1px solid #ddd;border-bottom: 1px solid #ddd;}
  .counter-dis{border-left: 1px solid #ddd;}
  .counter-add{border-right: 1px solid #ddd;color:#06c1ae;}
  .counter-num{padding: 3px 14px;border: 1px solid #ddd;}
</style>

增减数量后emit给父组件即可

最终订单提交页面在真机上显示如下

image.png

10、订单详情页面

订单详情页面由订单列表页进入,主要就是商家信息和订单信息的展示

  <div class="container ub-box">
    <scroll-view scroll-y style="height: 100vh" scroll-top="0">
     <dl class="ub-box ub-col z-width-100-percent">
      <dd class="item z-width-100-percent ub-box ub-ver z-box-sizing-border z-bg-color-fff">
        <p class="ub-box">
          <img class="z-img-cover" :src="formdata.img" />
        </p>
        <div class="ub-flex-1 ub-box ub-col z-padding-h-10-px z-box-sizing-border">
          <p class="z-font-size-15 z-color-333 z-margin-bottom-3-px z-font-weight-bold z-lines-1-overflow-hidden">{
   {formdata.mainTitle}}</p>
          <p class="z-font-size-14 z-color-666 z-margin-bottom-3-px z-lines-1-overflow-hidden">{
   {formdata.subTitle}}</p>
          <p class="z-font-size-14 z-margin-bottom-3-px" style="color:#06c1ae">¥{
   {formdata.price}}</p>
        </div>
      </dd>
      <dd class="item z-margin-top-8-px z-width-100-percent ub-box ub-ver ub-col z-box-sizing-border z-bg-color-fff">
        <span class="z-font-size-15 z-color-333 z-margin-bottom-8-px z-font-weight-bold">商家信息</span>
        <div class="z-width-100-percent ub-box ub-between">
          <span class="z-font-size-14 z-color-666">{
   {formdata.sellerName}}</span>
          <span @click.stop="clickContact()" class="ub-box z-padding-h-10-px z-box-sizing-border" style="border-left:1px solid #eee">
            <i class="iconfont icon-dianhua z-font-size-22" style="color:#06c1ae"></i>
          </span>
        </div>
      </dd>
       <dd class="item z-margin-top-8-px z-width-100-percent ub-box ub-ver ub-col z-box-sizing-border z-bg-color-fff">
        <span class="z-font-size-15 z-color-333 z-margin-bottom-8-px z-font-weight-bold">套餐</span>
        <div class="ub-box ub-ver ub-between z-width-100-percent z-border-bottom-1-eee z-padding-v-10-px">
          <span class="z-font-size-14 z-color-333">{
   {formdata.package.packageName}}</span>
          <span class="z-font-size-14 z-color-333">{
   {formdata.package.packagePrice}}</span>
        </div>
        <ul class="ub-box ub-col z-width-100-percent z-margin-top-8-px">
          <li v-for="(val, i) in formdata.package.notes" :key="i" class="z-font-size-14 z-color-333 z-lineHeight-22 z-margin-bottom-5-px">{
   {val}}</li>
        </ul>
      </dd>
      <dd style="padding:8px 50px" class="z-margin-top-8-px z-width-100-percent ub-box ub-ver ub-col z-box-sizing-border z-bg-color-fff">
        <span class="z-font-size-15 z-color-333 z-margin-bottom-8-px z-font-weight-bold">订单信息</span>
        <ul class="z-width-100-percent ub-box ub-col ub-ver">
          <li class="z-width-100-percent ub-box ub-between ub-ver z-margin-bottom-8-px">
            <span class="z-font-size-14 z-color-888 ub-flex-1 z-textAlign-left">订单号</span>
            <span class="z-font-size-14 z-color-888 ub-flex-2 z-textAlign-right">{
   {formdata.orderNum}}</span>
          </li>
          <li class="z-width-100-percent ub-box ub-between ub-ver z-margin-bottom-8-px">
            <span class="z-font-size-14 z-color-888 ub-flex-1 z-textAlign-left">购买手机号</span>
            <span class="z-font-size-14 z-color-888 ub-flex-2 z-textAlign-right">{
   {formdata.orderPhone}}</span>
          </li>
          <li class="z-width-100-percent ub-box ub-between ub-ver z-margin-bottom-8-px">
            <span class="z-font-size-14 z-color-888 ub-flex-1 z-textAlign-left">下单时间</span>
            <span class="z-font-size-14 z-color-888 ub-flex-2 z-textAlign-right">{
   {formdata.orderCreateTime}}</span>
          </li>
          <li class="z-width-100-percent ub-box ub-between ub-ver z-margin-bottom-8-px">
            <span class="z-font-size-14 z-color-888 ub-flex-1 z-textAlign-left">数量</span>
            <span class="z-font-size-14 z-color-888 ub-flex-2 z-textAlign-right">{
   {formdata.orderCount}}</span>
          </li>
          <li class="z-width-100-percent ub-box ub-between ub-ver">
            <span class="z-font-size-14 z-color-888 ub-flex-1 z-textAlign-left">总价</span>
            <span class="z-font-size-14 z-color-888 ub-flex-2 z-textAlign-right">{
   {formdata.orderTotalPrice}}</span>
          </li>
        </ul>
      </dd>
      <dd class="item z-margin-top-8-px z-width-100-percent ub-box ub-ver ub-col z-box-sizing-border z-bg-color-fff">
        <span class="z-font-size-15 z-color-333 z-margin-bottom-8-px z-font-weight-bold">提示</span>
        <p class="z-font-size-14 z-color-999 z-lineHeight-22 z-margin-bottom-8-px">您可以凭购买时所填写的手机号登录美团App进行评价、退款等更多操作</p>
        <span @click.stop="clickContact()" class="contactBtn z-width-100-percent ub-box ub-ver z-font-size-14 z-color-666">联系客服</span>
      </dd>
     </dl>
    </scroll-view>
  </div>
</template>
<script>
  export default {
    data () {
      return {
        formdata: {
          goodId: '100',
          mainTitle: '单人自助晚餐',
          subTitle: '单人自助晚餐',
          img: 'http://p0.meituan.net/200.0/deal/522fd16a9b25479496188b59476d1b941062402.jpg@206_0_828_828a%7C267h_267w_2e_90Q',
          sellerName: '索菲特大酒店锦厨国际餐厅自助餐',
          package: {
            packageName: '单人自助晚餐',
            packagePrice: '¥398(1位)',
            notes: [
              '单人自助晚餐:周一至周四18:00-21:00',
              '餐厅预定入口: https://tableplus.accorplus.com?vc=KweeZeenRestaurantAccorASE1187',
              '锦厨国际餐厅位于昆明索菲特大酒店49楼,能够360度鸟瞰春城美景。',
              '我们为您提供400种以上的餐食自助,全场酒水畅饮,包括葡萄酒、各色软饮及果汁。',
              '更有专属定制化服务:凡周年纪念日/生日当天到店就餐的客人,将免费提供蛋糕一个(此项仅针对提前至少一天进行预约并说明过情况的客人。)',
              '温馨提示:儿童按身高收费,具体是0-110cm儿童免费;110cm-140cm儿童半价;140cm以上的全价。 另:如遇特殊活动时,需根据店里实际情况按实际价格补差价。',
            ],
          },
          sellerTel: '',
          price: 308.00,
          orderNum: '4396693980',
          orderPhone: '184****3468',
          orderCreateTime: '2018/05/16 11:11:49',
          orderCount: '1',
          orderTotalPrice: '308',
        }
      }
    },
    methods: {
      clickContact() {
        wx.showActionSheet({
          itemList: ['客服电话:10107888'],
          success(res) {
            switch(res.tapIndex) {
              case 0:
                wx.makePhoneCall({phoneNumber: '10107888'})
                break
            }
          }
        })
      },
    },
    onShow() {
      wx.setNavigationBarTitle({title: '订单详情页'})
    }
  }
</script>
<style scoped>
  .container{width:100%;height:100vh;background:#f5f5f5}
  .item{border-bottom: 1px solid #f5f5f5;padding: 8px 10px;}
  .item img{width: 80px;height: 60px;border-radius: 3px}
  .contactBtn{padding: 8px 0;border: 1px solid #eee;}
</style>

最终订单详情页面在真机上显示如下

image.png

11、通用方法封装

开发完所有页面后,我们来封装一些通用函数,方便挂载到Vue原型上在任何页面使用

首先是Ajax封装,由于微信提供的request是类似Jquery的语法里带上各个回调函数,这让我们使用习惯Promise或者es7的async/await的异步编程风格后显得非常不舒服,所以我们将request封装成Promise风格,让我们可以在任何页面通过async/await来接收服务器的返回值

封装Ajax为Promise风格的函数如下

export function Ajax (opts, cb=function(){}) {
  wx.showLoading({title: '请求中...', mask: true})
  const {url, method='GET', data={}} = opts
  return new Promise((resolve, reject) => {
    wx.request({
      url,
      data,
      method,
      header: {"content-type": "application/json"},
      success(res) {
        resolve(res)
      },
      fail(err) {
        reject(err)
      },
      complete(res) {
        setTimeout(() => {
          wx.hideLoading()
          cb && cb(res)
        }, 1000)
      }
    })
  })
}

下面我们简单的封装一些常用的方法,如打开新窗口,返回上一级窗口和重定向

export function openWin (url) {
  wx.navigateTo({url: url})
}
// 关闭当前页面,跳转到应用内的某个页面
export function redirectTo (url) {
  wx.redirectTo({url: url})
}
// 返回上一级窗口
export function backBeaforWin () {
  wx.navigateBack({delta: 1})
}

最后在主程序入口里挂载即可

把通用方法挂载到Vue原型上
Vue.prototype.$openWin = openWin
Vue.prototype.$redirectTo = redirectTo
Vue.prototype.$backBeaforWin = backBeaforWin
Vue.prototype.$ajax = Ajax

12、Vuex的设计

我们在store里设置三个状态,分别为当前城市、用户是否登录标志和用户信息集合,并在mutations里提供更新维护这三个状态的方法接口即可

import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    curCity: '昆明',
    isLogin: false,
    userInfo: {
    	avatarUrl: '',
    	city: '',
    	gender: '',
    	nickName: '',
    	province: ''
    },
  },
  mutations: {
    updateCity: (state, change) => {
      state.curCity = change
    },
    updateIsLogin: (state, change) => {
  		state.isLogin = change
  	},
  	cleanUserInfo: (state) => {
  		state.userInfo = {
  			avatarUrl: '',
	    	city: '',
	    	gender: '',
	    	nickName: '',
	    	province: ''
  		}
  	},
    updateUser: (state, change) => {
      change.gender = change.gender === 1 ? '男' : '女'
      state.userInfo = change
    }
  }
})
export default store

最后将store挂载到Vue的原型上即可

把store挂载到Vue原型上
Vue.prototype.$store = store

源码截图:

在这里插入图片描述

说明

如果本项目对您有帮助,欢迎 “点赞,关注” 支持一下 谢谢~

源码获取关注公众号「码农园区」,回复 【uniapp源码】
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lwzhang1101/article/details/134810161

智能推荐

毕设分享 基于STM32的智能水产养殖系统_毕业设计水产养殖-程序员宅基地

文章浏览阅读238次。这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是毕设分享 基于STM32的智能水产养殖系统(源码+硬件+论文)学长这里给一个题目综合评分(每项满分5分)难度系数:3分工作量:3分创新点:4分包含内容。_毕业设计水产养殖

【资料分享】基于单片机大气压监测报警系统电路方案设计、基于飞思卡尔的无人坚守点滴监控自动控制系统设计(程序,原理图,pcb,文档)_基于单片机和无线通信的压强压力报警系统-程序员宅基地

文章浏览阅读1.2k次,点赞21次,收藏21次。如果我们说“10元给我汽车小零花钱妈妈”,或者“妈妈给我10亿人民币,我要买F-22”,妈妈就会觉得奇怪,听不懂我们的意思,或者理解错误,责备我们。汇编语言是计算机发展初期的一门语言,它的执行效率非常高,但是开发效率非常低,所以在常见的应用程序开发中不会使用汇编语言,只有在对效率和实时性要求极高的关键模块才会考虑汇编语言,例如操作系统内核、驱动、仪器仪表、工业控制等。我们说的是汉语,是“中国语言”,只要把我们的需求告诉父母,父母就会满足,我们用“中国语言”来控制父母,让父母做我们喜欢的事情。_基于单片机和无线通信的压强压力报警系统

Python里的全局变量、局部变量、类的self.*-程序员宅基地

文章浏览阅读853次,点赞20次,收藏21次。全局变量没有在任何函数内部定义,并且具有全局范围的变量;局部变量的定义:在函数内部定义的变量,范围仅限于该函数;是在一个函数内部声明一个全局变量,以便在函数内部对全局变量进行修改,这个全局变量本身已经定义过了,而不是我想当然认为的定义了一个全新的全局变量!️如果没有将其声明为全局变量,则在函数内部更改或创建的任何变量都是局部变量。当全局变量和局部变量的命名一样时,在一个函数内部还是会使用自己内部的局部变量;

国内可访问GPG Keyserver列表-程序员宅基地

文章浏览阅读1.7w次,点赞3次,收藏5次。apt-get update 或者aptitude update出现以下错误:The following signatures couldn't be verified because the public key is not available: : NO_PUBKEY B5B7720097BB3B58解决方法:1,从任何一个key server获得缺失的公钥B5B7720_keyserver

51-矩阵键盘和矩阵键盘密码锁_矩阵键盘密码锁如何不可见-程序员宅基地

文章浏览阅读907次,点赞3次,收藏4次。矩阵键盘和矩阵键盘密码锁_矩阵键盘密码锁如何不可见

vulnhub靶场——Hacker-Kid-v1-0-1_hacker_kid-程序员宅基地

文章浏览阅读5.9k次。vulnhub靶场——Hacker-Kid-v1-0-1 WP_hacker_kid

随便推点

使用Autolayout实现UITableView的Cell动态布局和高度动态改变_ios cell布局完成会调用什么方法?-程序员宅基地

文章浏览阅读604次。http://blog.163.com/china_uv/blog/static/1171372672014111681232340/本文翻译自:stackoverflow有人在stackoverflow上问了一个问题:如何在UITableViewCell中使用Autolayout来实现Cell的内容和子视图自动计算行高,并且能够保持平滑滚动的?_ios cell布局完成会调用什么方法?

《剑指 Offer》专项突破版 - 面试题 88 : 动态规划的基础知识(C++ 实现)-程序员宅基地

文章浏览阅读1k次,点赞29次,收藏16次。面试题 88 : 爬楼梯的最少成本(C++ 实现)

argmin是什么意思-程序员宅基地

文章浏览阅读9.3k次,点赞13次,收藏11次。举个简单的例子,考虑一个函数 f(x),其中 x 是实数。如果 f(x) 在 x = 3 时取得最小值,那么。经常用于描述需要找到某个函数的最小值时,所需的自变量的值。是一个数学术语,用于表示一个函数在其定义域中取得最小值的参数值(自变量的值),而不是最小值本身。表示函数的自变量(通常是一个实数或向量),当输入到该函数后,使函数取得最小值的自变量的值。的名称来源于 “argument of the minimum”,意思是最小值的参数。这表示当 x = 3 时,函数 f(x) 的值最小。_argmin

ssm/php/node/python基于人脸识别的学生上课考勤与监控系统_人脸识别考勤系统上课-程序员宅基地

文章浏览阅读919次,点赞21次,收藏12次。该系统能够有效提高考勤的准确性和效率,减少人为错误和作弊行为,确保考勤数据的真实性和可靠性。这一技术的应用也体现了教育信息化的发展趋势,有助于培养学生的信息素养,为他们适应未来社会的发展奠定基础。在教育领域,传统的考勤方式如点名、签到等不仅耗时耗力,而且容易出现代签、漏签等问题,影响了考勤的准确性和效率。这种系统可以无缝集成到现有的校园网络中,通过实时比对数据库中存储的学生面部信息,快速准确地完成考勤工作,大大减轻了教师的管理负担,提高了教学管理的效率和质量。文末可领取本课题的JAVA源码参考。_人脸识别考勤系统上课

该选择算法还是开发_开发与算法-程序员宅基地

文章浏览阅读8.5k次,点赞10次,收藏21次。最近有很多同学问小猿,我该选择算法还是开发?这本来不应该是一个问题,一个标准的答案就是你喜欢什么就做什么。但是,因为这样那样的问题,很动人开始动摇,我们把大家动摇的原因总结了一下,我们一条一条为大家分析:我喜欢算法,但是算法竞争太大了,我想转开发我读研了,感觉不做算法亏了我非科班,想转计算机,应该学什么我喜欢算法,但是算法竞争太大了,我想转开发算法岗五大标配:论文、比赛、实习、项目..._开发与算法

一文解决scrapy带案例爬取当当图书_scrapy爬虫当当网-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏43次。Scrapy框架简介Scrapy的五大组件Spiders(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。Scheduler(调度器):它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。Down_scrapy爬虫当当网