尚硅谷外卖项目笔记一

目录

1. 项目准备

2  路由的使用

3  stylus

4  swiper组件的使用

5  vuex

6  路由组件的meta属性

7 异步数据的请求

8 ajax跨域问题:配置代理

9 异步数据的获取

10 异步显示轮播图

11 登录/注册界面


1. 项目准备

1.1 项目描述

该项目基于vue2实现的一个外卖软件,可以实现登录、注册、查看外卖商家等功能

1.2 技术选型

1.3 API接口

1) 根据经纬度获取位置信息

2)获取食品分类列表

3) 根据经纬度获取商铺列表

1.4 从中学到什么?

1)项目的搭建

使用脚手架搭建项目

npm install -g @vue/cli          //安装vue脚手架,如果之前安装过就不再需要安装

npm create  项目名               //创建vue2项目

npm install                            //安装package.json里面的内容   

npm run serve                      //启动热加载

有关npm的相关指令说明

npm install moduleName  安装模块到项目node_modules目录下

npm install -g moduleName  安装模块到全局,不会在项目node_modules目录中保存模块包

npm install --save moduleName 安装模块到项目node_modules目录下,在package.json文件的dependencies节点写入依赖

npm install --save-dev moduleName安装模块到项目node_modules目录下,在package.json文件的devDependencies节点写入依赖

使用原则

开发时需要使用--save-dev,如gulp ,压缩css、js的模块;

部署后需要使用--save,如express, router等

2  路由的使用

详见以下文章

Vue学习笔记|路由、详细、入门_***无名小卒的博客-CSDN博客

3  stylus

npm install stylus@0.54.8  stylus-loader@3.2.2

需要主要版本冲突,以上指令适用于vue2框架

stylus是css预处理器,作用让css代码的编写更加结构化

4  swiper组件的使用

swiper是实现轮播图的一个插件

5  vuex

管理从后台获取的状态数据

Vue学习笔记|vuex_***无名小卒的博客-CSDN博客

6  路由组件的meta属性

如登录页面不需要底部的tab切换,因此可以给需要底部的tab切换的路由加上showFooter属性

   //如登录页面不需要底部的tab切换,因此可以给需要底部的tab切换的路由加上showFooter属性
   {
        path:'/order',
        component:Order,
        meta:{
            showFooter:true
        }
    }

在全局组件中给底部的tab组件加上判断条件,当跳转的路由需要底部tab再显示,如若不需要便不显示

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

7 异步数据的请求

7.1 请求函数封装:使用Promise和axios实现封装,其中封装GET请求和POST请求两种请求方式,使用Promise实现异步任务,在Promise中发送请求;若发送请求则调用resolve方法,若发送失败,则调用reject方法

/*
* 封装ajax请求函数
* 返回值:promise对象
* */
import axios from 'axios'
export default function ajax (url, data = {}, type = 'GET') {
  return new Promise(function (resolve, reject) {
    let promise
    // 执行异步ajax请求
    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(function (response) {
      // 成功了调用resolve
      resolve(response.data)
    }).catch(function (err) {
      // 失败了调用reject
      reject(err)
    })
  })
}

7.2 接口的封装

根据后台的接口文档,一共有多少个接口便封装成多少个请求,该在Vue直接调用请求

/*
* 包含n个接口请求函数的模块
* 函数返回值:promise对象
* */
import ajax from './ajax'

const BASE_URL='api'

// 根据经纬度获取位置信息
export const reqAddress = (geohash)=> ajax(`${BASE_URL}/position/${geohash}`)


//获取食品分类列表
export const reqCategorys = ()=> ajax(`${BASE_URL}/index_category`)

//根据经纬度获取商铺列表
export const reqShops = (latitude,longitude)=> ajax(`${BASE_URL}/shops`,{latitude,longitude})

7.3 相关依赖

npm i axios --save    //安装axios依赖

8 ajax跨域问题:配置代理

该项目为前后端分离的项目,前端向后台发送ajax请求,会发生跨域,解决跨域的方法:在前端设置代理,拦截请求,代理再将请求转发给服务器

proxyTable: {
      '/api': { // 匹配所有以 '/api'开头的请求路径
        target: 'http://localhost:4000', // 代理目标的基础路径
        changeOrigin: true, // 支持跨域
        pathRewrite: {// 重写路径: 去掉路径中开头的'/api'
          '^/api': ''
        }
      }
    }

9 异步数据的获取

使用vuex来实现对数据的管理。

首先创建相关的模块。index|state|mutations|actions|getters|mutation-type

actions用于响应组件中的动作,在该项目中,action中主要实现发送ajax请求,并将获取的数据commit给mutations

mutations用于操作数据,改变state中的数据

state中封装要接收的数据,state中的数据是直接与页面交互的一层

在组件中获取数据

1.向actions分发请求,异步获取数据,并放到state中

mounted(){
          //获取数据
          this.$store.dispatch('getCategorys')
          this.$store.dispatch('getShops')
        }

2. 获取state中数据

使用mapState使用数组语法获得数据,也可以使用计算属性去获取state中的数据。在组件中就可以直接使用该数据

import {mapState} from 'vuex'
computed:{
            ...mapState(['address','categorys'])
         }

模板中数据的来源

data(自身的数据)、props(外部传入的数据)、computed(计算属性)根据data/props/state/getters获取数据

10 异步显示轮播图

使用vuex获取轮播图的数据

对数据进行整合,将一维数组转为二维数组

使用Swiper显示轮播,在界面更新之后创建Swiper对象

//  根据categorys一维数组生成一个二维数组
            categorysArr(){
              const {categorys}=this
              const arr=[]
              //准备一个小数组
              let minArr=[]
              //遍历categorys
              categorys.forEach(item=>{
                //如果当前小数组满了,创建一个新的
                if(minArr.length===8){
                  minArr=[]
                }
                //如果当前小数组为空,将小数组保存到大数组
                if(minArr.length===0){
                  arr.push(minArr)
                }
                //将食品分类的数据放入小数组
                minArr.push(item)
              })
              return arr
            }

使用Swiper显示轮播,在界面更新之后创建Swiper对象

使用waich+$nextTick()方法

this.$nextTick()将回调延迟到下次DOM更新循环之后执行。在修改数据之后立即使用它,然后等待DOM更新即可。

 watch:{
          categorys(value){
            //界面更新就立即創建Swiper對象
            this.$nextTick(()=>{
              //一旦完成界面更新,立即調用Swiper(此語句寫在數據更新之後)
              new Swiper('.swiper-container',{
                loop: true,
                //分页器
                pagination:{

                  el: '.swiper-pagination'
                }
              })
            })
          }
      },

11 登录/注册界面

1)切换登录的方式

给两个tab动态绑定class,在data中设置一个属性loginWay,代表登录的方式,值为布尔类型,当为true时为短信登录,反之为密码登录。使用对象的方法动态绑定class,当class中的on为true时,就会出动on中的样式

  <a href="javascript:;" :class="{on:loginWay}" @click="loginWay=true">短信登录</a>
  <a href="javascript:;" :class="{on:!loginWay}" @click="loginWay=false">密码登录</a>

 如图当切换tab时,会显示不一样的form,同样给这两个表单动态绑定class,先将整个div设置为隐藏,当绑定的class属性值为true时,就将display设置为true

以下css语法使用stylus

  .login_content
                >form
                    >div
                        display none
                        &.on
                            display block

           

 2) 手机号合法检查

使用正则表达式对数据进行验证,返回true则手机号码正确,可以发送验证码,false则不能发送验证码

rightPhone(){
          return /^1\d{10}$/.test(this.phone)
        }

3) 验证码发送倒计时实现

发送验证码按钮disable属性

当rightPhone为true,即手机号码正确时,按钮可以正常使用,即disable为false

当rightPhone为false,即手机号码错误时,按钮不能正常使用,即disable为true

计时和获取验证码按钮的切换

使用三木表达式,其中computeTime用于倒计时,当其>0时,显示已发送xxs,当其=0,显示获取验证码

<button :disabled="!rightPhone"
         class="get_verification"
        :class="{right_phone:rightPhone}"
        @click.prevent="getCode">
    {{computeTime ? `已发送(${computeTime}s)`: '获取验证码'}}
</button>

实现计时

当点击按钮时,触发getCode方法,该方法使用setInterval实现倒计时的功能

   getCode(){
          //当计时器没有工作时
          if(!this.computeTime){
            //启动倒计时
            this.computeTime=30
            const intervalId=setInterval(()=>{
              this.computeTime--
              if(this.computeTime<=0){
                //停止计时
                clearInterval(intervalId)
              }
            },1000)
            //发送ajax请求,获取验证码
          }
        }

4) 切换显示和隐藏密码

         

<!--设置按钮的颜色,打开按钮绿色,关闭按钮灰色-->
<div class="switch_button"
     :class="showPwd ? 'on':'off'"
     @click="showPwd=!showPwd" >
     <!--小圆圈-->
     <div class="switch_circle" :class="{right:showPwd}"></div>
     <!--文字-->
     <span class="switch_text">{{showPwd ? 'abc':'...'}}</span>
</div>

该按钮由外圈,小圆圈,以及字体组成

给外圈动态绑定class,使用三目表达式,来动态绑定两种样式,白色隐藏密码,绿色显示密码

给小圆圈动态邦栋class,为true时,设置一个动画,向右滑动

文字同理

 5) 前台验证码提示

前台验证登录主要验证是否非空,使用正则表达式验证手机号码是否正确

                                

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值