1. 程式人生 > >基於vue來開發一個仿餓了麽的外賣商城(二)

基於vue來開發一個仿餓了麽的外賣商城(二)

off shang tex lin lips 搜索 alt size :focus

一、抽出頭部作為一個組件,在底部導航的時候可以相應的顯示不同的標題

技術點:使用slot進行組件間的通信;父組件給子組件傳值(子組件裏面通過props接收父組件傳過來的數據)

查看鏈接:https://blog.csdn.net/sinat_17775997/article/details/52484072

技術分享圖片
//components/HeaderTop/HeaderTop.vue
<template>
    <header class="header">
            <slot name="search"></slot>
            <a class="header_title">
                <span class="header_title_text ellipsis">{{title}}</span>
            </a>
            <slot name="login"></slot>
        </header>
</template>

<script>
export 
default { props: { title: String } }
HeaderTop.vue
技術分享圖片
<template>
    <HeaderTop title="南昌市華東交通大學南區">
            <router-link slot="search" to="/search" class="header_search">
                <i class="iconfont icon-sousuo"></i>
            </router-link>
            <router-link slot="login" to="/login" class="header_login">
                <span class="header_login_text">登錄|註冊</span>
            </router-link>
        </HeaderTop>
</template>

<script>
import HeaderTop from 
‘../../components/HeaderTop/HeaderTop.vue‘ import ShopList from ‘../../components/ShopList/ShopList.vue‘ export default { components: { HeaderTop, ShopList } </script>
Msite.vue
技術分享圖片
<template>
<HeaderTop title="訂單列表"></HeaderTop>
</template>
<script>
import HeaderTop from 
‘../../components/HeaderTop/HeaderTop.vue‘ export default { components: { HeaderTop } } </script>
Order.vue 技術分享圖片
<template>
<HeaderTop title="搜索"></HeaderTop>
</template>
<script>
import HeaderTop from ‘../../components/HeaderTop/HeaderTop.vue‘
export default {
  components: {
    HeaderTop
  }
}
</script>
Search.vue 技術分享圖片
<template>
<HeaderTop title="我的"></HeaderTop>
</template>
<script>
import HeaderTop from ‘../../components/HeaderTop/HeaderTop.vue‘
export default {
  components: {
    HeaderTop
  }
}
</script>
Profile.vue

二、抽出商家列表編輯成單獨組件

三、編輯登錄界面

提示:返回前面的路由使用 $router.back()

技術分享圖片
<template>
    <div class="loginContainer">
        <div class="loginInner">
            <div class="login_header">
                <h2 class="login_logo">餓了麽</h2>
                <div class="login_header_title">
                    <a href="javascript:;" class="on">短信登錄</a>
                    <a href="javascript:;">密碼登錄</a>
                </div>
            </div>
            <div class="login_content">
                <form>
                    <div :class="on">
                        <section class="login_message">
                            <input type="tel" maxlength="11" placeholder="手機號">
                            <button disabled="disabled" class="get_verification">獲取驗證碼</button>
                        </section>
                        <section class="login_verification">
                            <input type="tel" maxlength="8" placeholder="驗證碼" v-model="code">
                        </section>
                        <section class="login_hint">
                            溫馨提示:未註冊餓了麽帳號的手機號,登錄時將自動註冊,且代表已同意
                            <a href="javascript:;">《用戶服務協議》</a>
                        </section>
                    </div>
                    <div>
                        <section>
                            <section class="login_message">
                                <input type="text" maxlength="11" placeholder="手機/郵箱/用戶名">
                            </section>
                            <section class="login_verification">
                                <input type="text" maxlength="8" placeholder="密碼">
                                <div class="switch_button off">
                                    <div class="switch_circle"></div>
                                    <span class="switch_text">...</span>
                                </div>
                            </section>
                            <section class="login_message">
                                <input type="text" maxlength="11" placeholder="驗證碼">
                                <img class="get_verification" src="./images/captcha.svg" alt="captcha">
                            </section>
                        </section>
                    </div>
                    <button class="login_submit">登錄</button>
                </form>
                <a href="javascript:;" class="about_us">關於我們</a>
            </div>
            <span href="javascript:" class="go_back" @click="$router.back()">
                <i class="iconfont icon-fanhuijiantou"></i>
            </span>
        </div>
    </div>
</template>

<script>
export default {}
</script>

<style lang="stylus" rel="stylesheet/stylus">
  @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 #0090ff
          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 #0090ff
              font-weight 700
              border-bottom 2px solid #0090ff
      .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 #0090ff
            .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
                &.right_phone
                  color black
            .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 #0090ff
                >.switch_circle
                  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
                  &.right
                    transform translateX(30px)
            .login_hint
              margin-top 12px
              color #999
              font-size 14px
              line-height 20px
              >a
                color #0090ff
          .login_submit
            display block
            width 100%
            height 42px
            margin-top 30px
            border-radius 4px
            background #0090ff
            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>
Login.vue

然後註冊Login路由

router/index.js

技術分享圖片
//引入組件
import Login from ‘../pages/Login/Login.vue‘

 {
      path: ‘/login‘,
      component: Login
    }
View Code

四、控制底部導航的顯示隱藏。

註意:此時底部導航FooterGuide僅僅在Msite,Order,Search,Profile才顯示,Login上不會顯示。

技術點:v-show="$route.meta.show"

查看鏈接:http://www.cnblogs.com/nns4/p/8589539.html

https://segmentfault.com/q/1010000007648124

技術分享圖片
<template>
    <div id="app">
        <router-view/>
        <FooterGuide v-show="$route.meta.showFooter"></FooterGuide>
    </div>
</template>
App.vue

router/index.js

技術分享圖片
export default new Router({
  routes: [
    {
      path: ‘/‘,
      redirect: ‘/msite‘
    },
    {
      path: ‘/msite‘,
      component: Msite,
      meta: {
        showFooter: true
      }
    },
    {
      path: ‘/search‘,
      component: Search,
      meta: {
        showFooter: true
      }
    },
    {
      path: ‘/order‘,
      component: Order,
      meta: {
        showFooter: true
      }
    },
    {
      path: ‘/profile‘,
      component: Profile,
      meta: {
        showFooter: true
      }
    },
    {
      path: ‘/login‘,
      component: Login
    }
  ]
})
index.js

從這開始做後臺數據交互應用

五、封裝ajax請求。

api/ajax.js

提示:使用axios

技術分享圖片
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)
        })
    })
}
View Code

然後根據api接口類型設置請求函數的路由

api/index.js

技術分享圖片
import ajax from ‘./ajax.js‘

// 根據經緯度獲取位置詳情
export const reqAddress = (geohash) => ajax(`/position/${geohash}`)

// 獲取食品的分類列表
export const reqFoodCategories = () => ajax(‘/index_category‘)

// 根據經緯度獲取商鋪列表
export const reqShops = (longitude,latitude) => ajax(‘/shops‘,{longitude,latitude})

// 賬號密碼登錄
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‘)
View Code

六、配置webpack實現跨域

查看鏈接:https://www.cnblogs.com/zishang91/p/8909900.html

https://segmentfault.com/a/1190000011007043

config/index.js

技術分享圖片
proxyTable: {
      ‘/api‘:{ // 配置所有以api開頭的請求路徑
      target: ‘http://localhost:4000‘, // 代理目標的基礎路徑
      changeOrigin: true, //支持跨域
      pathRewrite: {
        ‘^/api‘: ‘‘
      }
      }
    },
View Code

基於vue來開發一個仿餓了麽的外賣商城(二)