web前端不用怕,外卖平台的项目开发流程,大全!!

项目开发流程

1. 创建客户端项目

1.1 使用 vue-cli(脚手架)搭建项目

#在Github新建Vue-MintShop项目,然后clone到本地
git clone git@github.com:W-Qing/Vue-MintShop.git
cd Vue-MintShop
#创建客户端项目
vue init webpack mintshop-client
cd mintshop-client
npm install
npm run dev 访问: localhost:8080

1.2 项目结构分析

**MintShop-client **

  • |-- build : webpack 相关的配置文件夹(基本不需要修改)
  • |-- build : webpack 相关的配置文件夹(基本不需要修改)
  • |-- config: webpack 相关的配置文件夹(基本不需要修改)
  • |-- index.js: 指定的后台服务的端口号和静态资源文件夹
  • |-- node_modules
  • |-- src : 源码文件夹
  • |-- main.js: 应用入口 js (初始化vue实例并使用需要的插件 )
  • |-- static: 静态资源文件夹
  • |-- .babelrc: babel 的配置文件
  • |-- .editorconfig: 通过编辑器的编码/格式进行一定的配置
  • |-- .eslintignore: eslint 检查忽略的配置
  • |-- .eslintrc.js: eslint 检查的配置
  • |-- .gitignore: git 版本管理忽略的配置
  • |-- index.html: 默认的主渲染页面文件
  • |-- package.json: 应用包配置文件
  • |-- README.md: 应用描述说明的 readme 文件

1.3 编码测试与打包发布项目

  • 编码测试

    npm run dev

    访问: http://localhost:8080

    编码, 自动编译打包(HMR), 查看效果

  • 打包发布

    npm run build

    npm install -g serve

    serve dist

    访问: http://localhost:5000

2. 功能需求分析

  • 开发前应该首先完成功能模块的分析设计,这里我们可以直接运行项目查看功能演示 自己总结项目功能需求

3. 开发资源准备

4. Css Reset、Fastclick与Stylus

4.1 Css Reset

  • 在项目主目录下的static文件夹内新建css文件夹

  • 在css文件夹内新建重置样式文件reset.css

  • 在index.html 中引入

    <link rel="stylesheet" href="/static/css/reset.css">
    

4.2 Fastclick

当用户一次点击屏幕之后,浏览器并不能立刻判断用户是要进行双击缩放,还是想要进行单击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。 于是,300 毫秒延迟就这么诞生了。

  • 安装fastclick库 解决点击响应延时 0.3s 问题

    npm Install fastclick --save
    
  • 在main.js中引入,并绑定到body

    import FastClick from 'fastclick'
    FastClick.attach(document.body);
    

4.3 Stylus

  • 安装stylus依赖包

    npm install stylus stylus-loader --save-dev
    
  • 在common文件夹下新建stylus文件夹

  • 在stylus文件加下面新建mixins.styl文件

  • 注意在组件内编写样式时要声明lang和rel

    <style lang="stylus" rel="stylesheet/stylus">
    

5. 源码目录设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-naRIF3Rr-1615041312256)(http://owoccema2.bkt.clouddn.com/Readme/vue/mintshop.png)]

6. Vue组件化

6.1 分析整个项目的 vue 组件结构

src

  • |-- components------------非路由组件文件夹
  • |-- FooterGuide---------------底部组件文件夹
    • |-- FooterGuide.vue--------底部组件 vue
  • |-- pages-----------------路由组件文件夹
    • |-- Msite---------------首页组件文件夹
      • |-- Msite.vue--------首页组件 vue
    • |-- Search----------------搜索组件文件夹
      • |-- Search.vue---------搜索组件 vue
    • |-- Order--------------订单组件文件夹
      • |-- Order.vue-------订单组件 vue
    • |-- Profile--------------个人组件文件夹
      • |-- Profile.vue-------个人组件 vue
  • |-- App.vue---------------应用根组件 vue
  • |-- main.js---------------应用入口 js
  1. 页面底部的FooterGuide组件只是用来放pages里的组件的容器,所以它不是路由组件
  2. 页面最上面的标题栏在我们的项目中属于路由组件的组成部分(与中间内容部分在一起)
  3. 但每个路由组件中都有最顶部的组件且相似度很高,所以可以将其抽取成为一个单独的组件

6.2 编写vue组件模板文件

  • pages文件夹下的各个vue组件文件及App.vue和FooterGuide.vue都是这个初始空白模板
<template>
  <div>App vue template</div>
</template>

<script>
  export default {}
</script>

<style lang="stylus" rel="stylesheet/stylus">
</style>

7. 引入Vue-router

###7.1 下载vue-router

#创建项目时已下载
npm install vue-router --save

7.2 编写router文件夹下的index.js

 /*
   路由模块 
 */
 import Vue from 'vue'
 import VueRouter from 'vue-router'
 // 引入路由组件文件夹下的组件
 import Msite from '../pages/Msite/Msite.vue'
 import Search from '../pages/Search/Search.vue'
 import Order from '../pages/Order/Order.vue'
 import Profile from '../pages/Profile/Profile.vue'
 // 全局注册Vue-router组件
 Vue.use(VueRouter)
 
 // 配置路由表并导出
 export default new VueRouter({
   
   //去掉地址中的哈希#
   mode: 'history',
   routes: [{
   
       path: '/',
       redirect: '/msite'
     },
     {
   
       path: '/msite',
       component: Msite,
     },
     {
   
       path: '/search',
       component: Search,
     },
     {
   
       path: '/order',
       component: Order,
     },
     {
   
       path: '/profile',
       component: Profile,
     }
   ]
 })

7.3 编写应用的入口文件main.js

// 引入路由 其实就是引入上一步配置好的路由表
import router from './router'

new Vue({
   
  el: '#app',
  render: h => h(app),
  // 为根组件加入路由
  router
})

7.4 在App.vue里使用router-view

<template>
  <!-- 修改应用组件的模板 -->
  <div id="app">
    <!-- 设置路由组件的视图位置 -->
    <router-view></router-view>
    <!-- 并放置非路由组件 -->
    <FooterGuide></FooterGuide>
  </div>
</template>

<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>
  • App.vue里的根元素<div id="app"></div>与外层被注入框架index.html中的<div id="app"></div>是一致的
  • index.html中的<div id="app"></div>是指定绑定目标为元素的根路径,而App.vue文件里的<div id="app"></div>则是提供注入绑定元素的内容,两者在运行时指的是同一个DOM元素

7.5 运行并请求不同路由路径查看效果

通过切换url地址里的hash值(miste/order/search/profile),页面会显示不同的路由模板内容。

8. 编写组件代码

8.1 FooterGuide组件

功能及实现

  1. 通过编程式导航实现路由的切换显示($router)
  2. 通过动态 class 和$route.path 来实现 tab 样式切换
  3. 通过阿里图标库, 显示导航图标

代码

<footer class="footer_guide border-1px">
    <a href="javascript:;" class="guide_item on">
    <span class="item_icon">
    <i class="iconfont icon-food"></i>
    </span>
    <span>外卖</span>
    </a>
    <!--其他三部分类似-->
</footer>
<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 center
    margin 5px
    color #999999
    &.on
      color #02a774
    span
      font-size 12px
      margin-top 2px
      margin-bottom 2px
      .iconfont
        font-size 22px
</style>

此时,页面已达到理想效果。接着修改template模板,为其加入路由与样式的切换控制。

<div class="guide_item" @click="goto('/msite')" :class="{on: isCurrent('/msite')}">
  <span class="item_icon">
  <i class="iconfont icon-food"></i>
  </span>
  <span>首页</span>
</div>
<!--其他三个部分类似,只是路由不同-->

再补充相应的函数方法

export default {
   
  methods: {
   
    goto (path) {
   
      this.$router.replace(path)
    },
    isCurrent (path) {
   
      // console.log(this.$route.path)
      return this.$route.path === path
    }
  }
}

至此,底部组件完成,可实现点击不同的选项切换不同的路由组件。

8.2 各导航路由组件

8.2.1 Msite组件

功能区域划分

  1. 最顶部的title标题栏部分
  2. 上方的nav轮播区域
  3. 商家列表展示区域

图片资源

Msite组件页面的轮播图及商家列表都需要用到一些图片资源文件,所以在msite.vue同级目录下新建images文件夹,以便放置各种不同类型的图片资源。

代码

<template>
  <section class="msite">
    <!--首页头部title-->
    <!--由msite_header改成header-->
    <header class="header">
      <span class="header_search">
        <i class="iconfont icon-sousuo"></i>
      </span>
      <span class="header_title">
        <span class="header_title_text ellipsis">芝罘区鲁东大学北区(青年南路)</span>
      </span>
      <span class="header_login">
        <span class="header_login_text">登录|注册</span>
      </span>
    </header>
    <!--首页导航轮播-->
    <nav class="msite_nav">
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <a href="javascript:" class="link_to_food">
              <div class="food_container">
                <img src="./images/nav/1.jpg">
              </div>
              <span>甜品饮品</span>
            </a>
            <a href="javascript:" class="link_to_food">
              <div class="food_container">
                <img src="./images/nav/2.jpg">
              </div>
              <span>商超便利</span>
            </a>
           <!--下面的图片省略-->
          </div>
          <div class="swiper-slide">
            <a href="javascript:" class="link_to_food">
              <div class="food_container">
                <img src="./images/nav/9.jpg">
              </div>
              <span>甜品饮品</span>
            </a>
            <!--同样省略-->
          </div>
        </div>
        <!-- 轮播图页码 -->
        <div class="swiper-pagination"></div>
      </div>
    </nav>
    <!--首页附近商家列表-->
    <div class="msite_shop_list">
      <div class="shop_header">
        <i class="iconfont icon-xuanxiang"></i>
        <span class="shop_header_title">附近商家</span>
      </div>
      <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 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_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>
    </div>
  </section>
</template>
<!--省略js-->

**要注意首页的头部标题部分的样式,在其他的组件中都可以进行重用。**所以将header标签的类名由msite_header改成header。接下来在其他组件中可以直接使用(当然header里的部分样式其他组件用不到,到时再进一步抽取公共的css样式。)

<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
      /*下面的样式省略*/
</style>

接下来的几个路由组件都类似,都是先修改template模版,然后引入mixins.styl 样式文件和上面提到的公共的header部分的样式。

8.2.2 Search组件
<section class="search">
    <header class="header">
      <div class="header_title">
        <span class="header_title_text">搜索</span>
      </div>
    </header>
    <form class="search_form" action="#">
      <input type="search" name="search" placeholder="请输入商家或美食名称"
    class="search_input">
      <input type="submit" class="search_submit">
    </form>
</section>
<!--省略js与style-->
8.2.3 Order组件

在order.vue同级目录下新建images文件夹,再新建order文件夹,存放订单组件用到的图片资源。

<div>
  <section class="order">
    <header class="header">
      <a class="header_title">
        <span class="header_title_text">订单列表</span>
      </a>
    </header>
    <section class="order_no_login">
        <img src="./images/order/person.png">
        <h3>登录后查看外卖订单</h3>
      <button>立即登陆</button>
    </section>
  </section>
</div>
<!--省略js与style-->
8.2.4 Profile组件
<div>
    <section class="profile">
      <header class="header">
        <a class="header_title">
          <span class="header_title_text">我的</span>
        </a>
      </header>
      <section class="profile-number">
        <a href="javascript:" class="profile-link">
          <div class="profile_image">
            <i class="iconfont icon-yonghuming"></i>
          </div>
          <div class="user-info">
            <p class="user-info-top">登录/注册</p>
            <p>
              <span class="user-icon">
                <i class="iconfont icon-msnui-tel icon-mobile"></i>
              </span>
              <span class="icon-mobile-number">暂无绑定手机号</span>
            </p>
          </div>
          <span class="arrow">
            <i class="iconfont icon-previewright"></i>
          </span>
        </a>
      </section>
      <section class="profile_info_data border-1px">
        <ul class="info_data_list">
          <a href="javascript:" class="info_data_link">
            <span class="info_data_top"><span>0.00</span>元</span>
            <span class="info_data_bottom">我的余额</span>
          </a>
          <a href="javascript:" class="info_data_link">
            <span class="info_data_top"><span>0</span>个</span>
            <span class="info_data_bottom">我的优惠</span>
          </a>
          <a href="javascript:" class="info_data_link">
            <span class="info_data_top"><span>0</span>分</span>
            <span class="info_data_bottom">我的积分</span>
          </a>
        </ul>
      </section>
      <section class="profile_my_order border-1px">
        <!-- 我的订单 -->
        <a href='javascript:' class="my_order">
          <span>
            <i class="iconfont icon-dingdan"></i>
          </span>
          <div class="my_order_div">
            <span>我的订单</span>
            <span class="my_order_icon">
              <i class="iconfont icon-previewright"></i>
            </span>
          </div>
        </a>
        <!-- 积分商城 -->
        <a href='javascript:' class="my_order">
          <span>
            <i class="iconfont icon-jifen"></i>
          </span>
          <div class="my_order_div">
            <span>积分商城</span>
            <span class="my_order_icon">
              <i class="iconfont icon-previewright"></i>
            </span>
          </div>
        </a>
        <!-- Mint外卖会员卡 -->
        <a href="javascript:" class="my_order">
          <span>
            <i class="iconfont icon-viptehuishiduan"></i>
          </span>
          <div class="my_order_div">
            <span>Mint外卖会员卡</span>
            <span class="my_order_icon">
              <i class="iconfont icon-previewright"></i>
            </span>
          </div>
        </a>
      </section>
      <section class="profile_my_order border-1px">
        <!-- 服务中心 -->
        <a href="javascript:" class="my_order">
          <span>
            <i class="iconfont icon-lianxikefu"></i>
          </span>
          <div class="my_order_div">
            <span>服务中心</span>
            <span class="my_order_icon">
              <i class="iconfont icon-previewright"></i>
            </span>
          </div>
        </a>
      </section>
    </section>
  </div>
<!--省略js与style-->

8.3 HeaderTop组件

8.3.1组件的构成分析
  1. 中间有一个固定的标题栏,只是用在不同的路由组件中显示的内容不同
  2. 标题栏两侧可能有搜索框之类的部分(Msite)也可能没有
  3. 此组件为非路由组件的公用组件(所以在Components文件夹内)
8.3.2 功能实现的技术
  • 标题栏两侧是否有其他部分,要用到slot插槽进行组件间通信
  • slot 通信是标签, 而不是单纯的数据
  • 中间标题栏接收的文本可以用props
8.3.3 组件代码
<template>
  <header class="header">
    <!-- 插槽是父组件与子组件的通讯方式,子组件中的slot可以显示父组件传递给子组件的内容 -->
    <slot name="left"></slot>
    <span class="header_title">
      <span class="header_title_text ellipsis">{
  {title}}</span>
    </span>
    <slot name="right"></slot>
  </header>
</template>

<script>
  export default {
    // 外部组件传递给此组件的属性
    props: {
      title: String
    }
  }
</script>
8.3.4 在路由组件中使用
  • 在要使用此头部组件的文件中引入并注册HeaderTop组件
//Msite、Order、Search、Profile中都要引入注册才能使用
import HeaderTop from '../../components/HeaderTop/HeaderTop.vue'
export default {
   
  components: {
   
    HeaderTop
  }
}
  • 然后使用<HeaderTop></HeaderTop>标签设置这个头部组件

    这里以Msite.vue为例,先删除静态模版里的Header部分,替换成HeaderTop组件

<!-- 使用 title 来给头部组件传递数据 -->
<HeaderTop title="芝罘区鲁东大学北区(青年南路)">
  <!-- 要使用slot="left"指定插入的插槽位置 -->
  <span class="header_search" slot="left">
    <i class="iconfont icon-sousuo"></i>
      </span>
  <span class="header_login" slot="right">
    <span class="header_login_text">
          登录|注册
    </span>
  </span>
</HeaderTop>
  • 在其他几个组件中的用法是一样的,同时还省去了slot插槽部分。

8.4 使用swiper插件实现轮播图

下载安装: npm install swiper --save

Msite.vue的HTML部分:

<!--在页面msite_nav导航部分使用swiper-->
<div class="swiper-container">
	<div class="swiper-wrapper">
        <div class="swiper-slide">1</div>
        <div class="swiper-slide">2</div>
        <div class="swiper-slide">3</div>
    </div>
    <!-- swiper轮播图圆点 -->
    <div class="swiper-pagination"></div>
</div>

script部分引入并初始化:

<script>
import Swiper from 'swiper'
//同时引入swiper的 css文件
import 'swiper/dist/css/swiper.min.css'
export default {
   
  //注意要在页面加载完成之后(mounted)再进行swiper的初始化
  mounted () {
   
    //创建一个swiper实例来实现轮播
    new Swiper('.swiper-container', {
   
      autoplay: true,
      // 如果需要分页器
      pagination: {
   
        el: '.swiper-pagination',
        clickable: true
      }
   })
  }
}
</script>

具体用法参考Swiper官方文档

8.5 拆分出商家列表ShopList组件

  1. 商家列表是位于首页轮播图下面的部分,可以拆分为一般组件
  2. 在components文件夹下新建ShopList文件夹并新建ShopList.vue文件
  3. 该组件中用到需要一些图片资源,所以在ShopList文件夹下还需要新建images文件夹
  4. 将原本放在Msite文件夹下的shop和stars图片资源移动到新建的images文件夹内 (其实都应该是动态地从后台获取)
  5. 将Msite.vue模板中的<div class="shop_container"></div>部分及相应的stylus样式代码移动到新建的ShopList.vue组件
  6. 注意还要引入公共的css代码mixins.styl
  7. 最后在Msite.vue中import引入商家列表组件并注册使用

8.6 Login组件

资源文件准备

  1. 登录组件为一级路由组件,所以在pages文件夹下新建Login文件夹和Login.vue
  2. template模板里会用到一张svg图片(静态的验证码图片),所以还要在Login文件夹下新建images文件夹

配置路由跳转

  • 将路由组件映射为路由,在router下的index.js文件里进行配置
  • 登录组件的路由是从个人中心Profile组件里跳转而来的,所以要修改Profile.vue
<!--将class为profile-link的a标签替换为router-link-->
<a href="javascript:" class="profile-link">
    ...
</a>
<!--但要注意不要忘记class类名-->
<router-link to="/Login" class="profile-link">
    <!--先不考虑未登录的情况-->
    ...
</router-link>

编写Login.vue代码

  • 利用@click="$router.back()"实现点击页面的箭头返回上一级路由/Profile的功能

实现控制Footer的显示隐藏

  • 已确定底部的四个路由组件需要显示Footer部分

  • 而Login组件为一级路由组件,且不需要显示底部的FooterGuide导航组件

  • 所以为路由组件添加meta元数据来标识是否显示Footer

    {
         
      path: '/msite',
      component: Msite,
      meta: {
         
        showFooter: true
      }
    },
    /*Order、Searh、Profile组件都要添加meta*/
    
  • 在App.vue组件中通过代表当前路由的$route就能得到添加的meta属性,然后根据属性值来确定是否显示FooterGuide组件

    <FooterGuide v-show="$route.meta.showFooter"></FooterGuide>
    

其他细节

  • 注意到一个问题,在一个路由组件(Msite)将页面下拉,再切换到其他路由组件(Profile),页面不会自动回到顶部。

    /*解决方法 其他页面中类似*/
    .profile
        width 100%
    	/*添加一行overflow hidden*/
        overflow hidden
    

9. 后台应用

9.1 说明

  1. 整个项目为前后端分离的项目:mintshop-client 与 mintshop-server
  2. 后台应用负责处理前台应用提交的请求, 并给前台应用返回 json 数据
  3. 前台应用负责展现数据, 与用户交互, 与后台应用交互

9.2 运行

  1. 确保启动 mongodb 服务
  2. 进入mintshop-server文件夹,启动服务器应用: npm start

9.3 API文档

具体API文档详见mintshop-server/API.md,然后可以使用Postman来进行接口测试

10. 前后台交互 ajax

  • 测试完后台接口,则需要写前后台交互的ajax文件
  • 在src/api文件夹下新建index.js与ajax.js
    • 首先需要安装axios npm install axios--save

10.1 封装ajax请求函数

  • 为了实现统一向后端发送请求数据,所以需要封装一个ajax请求函数
/*
ajax 请求函数模块
*/ 
import axios from 'axios'
/**
 * 向外部暴漏一个函数 ajax
 * @param {*} url 请求路径,默认为空
 * @param {*} data 请求参数,默认为空对象
 * @param {*} type 请求方法,默认为GET
 */
export default function ajax(url = '', data = {
   }, type = 'GET') {
   
  // 返回值 Promise对象 (异步返回的数据是response.data,而不是response)
  return new Promise(function (resolve, reject) {
   
    //(利用axios)异步执行ajax请求
    let promise // 这个内部的promise用来保存axios的返回值(promise对象)
    if (type === 'GET') {
   
      // 准备 url query 参数数据
      let dataStr = '' // 数据拼接字符串,将data连接到url
      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()
        resolve(response.data)
      })
      .catch(error => {
   
        // 失败回调reject()
        reject(error)
      })
  })
}
  • 通过对axios返回的promise对象再包装一层Promise的方法,来简化外部的调用

10.2 封装接口请求函数

  • 有了发送请求数据的ajax函数,还需要封装一些与后台交互的接口函数
  • 根据接口文档来定义接口请求函数
/*与后台交互模块 (依赖已封装的ajax函数)
 */
import ajax from './ajax'
/**
 * 获取地址信息(根据经纬度串)
 * 这个接口的经纬度参数是在url路径里的,没有query参数
 */
export const reqAddress = geohash => ajax(`/position/${
     geohash}`)
/**
 * 获取 msite 页面食品分类列表
 */
export const reqCategorys = () => ajax('/index_category')
/**
 * 获取 msite 商铺列表(根据query参数:经纬度)
 * 将经纬度两个数据作为一个参数对象传入
 * 也可以两个数据分别传入ajax, 然后再放入一个对象参数内, 如下面的手机号验证码接口
 */
export const reqShops = ({
   
  latitude,
  longitude
}) => ajax('/shops', {
   
  latitude,
  longitude
})
/**
 * 账号密码登录
 */
export const reqPwdLogin = (name, pwd, captcha) => ajax('/login_pwd', {
   
  name,
  pwd,
  captcha
}, 'POST')
/**
 * 获取短信验证码
 */
export const reqSendCode = phone => ajax('/sendcode', {
   
  phone
})
/**
 * 手机号验证码登录
 */
export const reqSmsLogin = (phone, code) => ajax('/login_sms', {
   
  phone,
  code
}, 'POST')
/**
 * 获取用户信息(根据会话)
 */
export const reqUser = () => ajax('/userinfo')
/*
 * 请求登出
 */
export const reqLogout = () => ajax('/logout')

10.3 配置代理并测试接口实现ajax跨域请求

问题分析:

  • 目前为止运行的所有页面都是静态页面

  • 接下来先测试使用封装的ajax接口请求函数来异步获取数据

    // 先在App.vue中引入封装的接口函数
    import {
         reqCategorys} from './api'
    // 然后再调用接口,测试打印数据
    export default {
         
      async mounted () {
         
        const result = await reqCategorys()
        console.log(result)
      },
      components: {
         
        FooterGuide
      }
    }
    
  • 打开浏览器,运行项目会报错GET http://local:4000/index_category 404(Not Foun

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值