硅谷外卖项目day02

day02

项目地址

一、异步数据

1、封装ajax:(第一天已写,这个很重要)

  • 要学会promise+axios封装ajax请求的函数
  • 要能封装每个接口对应的请求函数(根据接口定义ajax请求函数)
  • 解决ajax的跨域问题:配置代理,对代理的理解。
  • 配置--config--index.js
proxyTable: {
  '/api': { // 匹配所有以 '/api'开头的请求路径
    target: 'http://localhost:3000', // 代理目标的基础路径
    changeOrigin: true, // 支持跨域
    pathRewrite: {// 重写路径: 去掉路径中开头的'/api'
      '^/api': ''
    }
  }
}

2、vuex编码:

  1. 创建所有相关的模块: store/index|state|mutations|actions|getters|mutations-types
  2. 设计state:也就是从后台获取的数据存储在state中
    • 出现问题:对于暴露导入的理解
const state = {}
export default state
import state from './xxx.js'
//暴露时没有加{},在import时也不需要加{}
const state = {}
export default {state}
//export default {} 导出的是对象,那么引入的时候就要 import {state} from './xxx.js'
  1. 实现actions,此文件是用来异步获取数据的
    • 定义异步action: async/await
    • 流程: 发送ajax获取数据,commit提交给mutation
  2. 实现mutation:给状态赋值,也就是更新state数据
  3. 实现index:创建store对象(固定的模式)
  4. main.js: 配置store

3、组件异步显示数据,解决swiper动态加载数据问题

  1. 异步获取数据,解决swiper动态加载数据问题
    参考网址: https://www.jianshu.com/p/128f3c53b66f
    • 在mounted()通过$store.dispatch('actionName')来异步获取后台数据到state中
    • mapActions(['getAddress'])以数组形式映射模块中的方法,在mounted中调用也可以异步获取后台数据
import { mapActions } from "vuex";
methods: {
 //TODO: 方法2.以数组形式映射模块中的方法
 ...mapActions(['getAddress'])
},
mounted () {
 //TODO: 方法1.含有异步操作,例如向后台提交数据
 // this.$store.dispatch('getAddress')
 this.getAddress();
}
  1. 读取数据
    • mapState(['...'])读取state中数据到组件中
  2. 显示数据
    • 在模板中显示xxx数据

4、模板中显示数据的来源

  1. data:自身的数据(内部改变)
  2. props:外部传入的数据(外部改变)
  3. computed: 根据data/props/别的compute/state/getters(计算的数据)

5、异步显示轮播图

  1. 通过vuex获取foodCategorys数据(发请求,读取)
  2. 对获取的数据进行整合计算(一维变特定的二维数据)
  computed: {
    ...mapState(["categorys"]),
    /*
      根据categorys一维数组生成一个2维数组
      小数组中的元素个数最大是8
       */
    categorysArr() {
      //解构赋值
      const { categorys } = this;
      // 准备空的2维数组
      const arr = [];
      // 准备一个小数组(最大长度为8)
      let minArr = [];
      categorys.forEach(c => {
        // 如果当前小数组已经满了, 创建一个新的
        if (minArr.length === 8) {
          minArr = [];
        }
        // 如果minArr是空的, 将小数组保存到大数组中
        if (minArr.length === 0) {
          arr.push(minArr);
        }
        // 将当前分类保存到小数组中
        minArr.push(c);
      });
      return arr;
    }
  },
  1. 通过双循环对二维数组进行遍历显示,如果没有数据时,显示预加载图片
<nav class="msite_nav">
 <!-- 判断是否有数据 -->
 <div class="swiper-container" v-if="categorys.length">
   <div class="swiper-wrapper">
     <!-- 第一层遍历二维数组 -->
     <div class="swiper-slide" v-for="(categorys, index) in categorysArr" :key="index">
       <!-- 第二层遍历,对二维数组中的一维数组遍历 -->
       <a href="javascript:" class="link_to_food" v-for="(category, index) in categorys" :key="index">
         <div class="food_container">
           <img :src="baseImageUrl+category.image_url">
         </div>
         <span>{{category.title}}</span>
       </a>
     </div>

   </div>
   <!-- Add Pagination -->
   <div class="swiper-pagination"></div>
 </div>
 <!-- 没有数据时显示预加载svg -->
 <img src="./images/msite_back.svg" alt="back" v-else >
</nav>
  1. 使用Swiper显示轮播图,如何在界面更新之后创建Swiper对象?
    • 使用watch+$nextTick(),监视显示的数据,如果数据有值立即更新
  watch: {
    categorys(value) {
      // categorys数组中有数据了, 在异步更新界面之前执行
      // 使用setTimeout可以实现效果, 但不是太好
      /*setTimeout(() => {
       //创建一个Swiper实例对象,实现轮播
        new Swiper(".swiper-container", {
          loop: true, // 循环模式选项,可以循环轮播
          // 如果需要分页器
          pagination: {
            el: ".swiper-pagination"
          }
        });
      }, 100);*/
       // 界面更新就立即创建Swiper对象
        this.$nextTick(() => {// TODO: 一旦完成界面更新, 立即调用(此条语句要写在数据更新之后)
          // 创建一个Swiper实例对象, 来实现轮播
          new Swiper('.swiper-container', {
            loop: true, // 可以循环轮播
            // 如果需要分页器
            pagination: {
              el: '.swiper-pagination',
            },
          }) 
        })
    }
  }

二、登录/注册:界面相关效果

  1. 切换登录方式
  • 初始化一个boolean值(longinWay),true为短信登录,false为密码登录
  • 使用@click方法设置boolean值
  • 定义一个class类绑定此布尔值控制表单显示选择
    loginWay: true //true代表短信登陆, false代表密码
    登录方式切换.png

    登录方式切换.gif
  1. 手机号合法检查,发送验证码倒计时
  • 通过计算属性验证输入的手机号是否正确,正确时可以点击发送获取验证码,right_phone类改变字的颜色
 <section class="login_message">
  <input type="tel" maxlength="11" placeholder="手机号" v-model="phone">
  <!-- 计算属性验证输入的手机号是否正确,正确则能点击获取验证码,添加显示状态。 -->
  <!-- 表单里面的button默认行为是提交表单,要取消默认行为 -->
  <!-- 三目运算,模板字符串,如果时间大于0则显示当前秒数 -->
  <button
    :disabled="!rightPhone"
    class="get_verification"
    :class="{right_phone: rightPhone}"
    @click.prevent="getCode"
  >{{computeTime>0? `已发送(${computeTime}s)` :'获取验证码'}}</button>
</section>
data() {
  return {
    phone: "", // 手机号
    computeTime: 0, //计时时间
  }
},
computed: {
    rightPhone() {
      //使用计算属性测试输入的手机号是否正确,正确则显示类名
      return /^1\d{10}$/.test(this.phone);
    }
  },
methods: {
  //异步获取验证码
  getCode() {
    //如果当时没有计时
    if (!this.computeTime) {
      //启动倒计时
      this.computeTime = 30;
      //TODO: 间歇调用
      const intervalId = setInterval(() => {
        this.computeTime--;
        if (this.computeTime <= 0) {
          clearInterval(intervalId);
        }
      }, 1000);
    }
  }
}
手机号码检车,发送验证码倒计时.gif
  1. 切换显示或隐藏密码
  • 通过两个输入框,一个按钮,改变密码的显示与隐藏状态

showPwd: false, //是否显示密码

<section class="login_verification">
  <!-- 切换密码显示隐藏状态,改变按钮选择状态,默认为隐藏 -->
  <input type="text" maxlength="8" placeholder="密码" v-if="showPwd" v-model="pwd">
  <input type="password" maxlength="8" placeholder="密码" v-if="!showPwd" v-model="pwd">
  <!-- 点击改变类的状态和圆圈的移动 -->
  <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>
</section>
密码显示和隐藏.gif
  1. 前台验证提示
  • 学会如何使用模板组件
  • 调用--components-AlertTip-AlertTip.vue组件,使用提示框组件
<!-- 提示模板组件 -->
<template>
  <div class="alert_container">
    <section class="tip_text_container">
      <div class="tip_icon">
        <span></span>
        <span></span>
      </div>
      <p class="tip_text">{{alertText}}</p>
      <div class="confrim" @click="closeTip">确认</div>
    </section>
  </div>
</template>

<script>
  export default {
    props: {
      alertText: String  //传入的参数
    },

    methods: {
      closeTip() {
        // 分发自定义事件(事件名: closeTip)
        this.$emit('closeTip')
      }
    }
  }
</script>
<form @submit.prevent="login">
</form>
<!-- 调用组件,@closeTip自定义事件 -->
<AlertTip :alertText="alertText" v-show="alertShow" @closeTip="closeTip"/>
import AlertTip from "../../components/AlertTip/AlertTip.vue";
data() {
  return {
      alertText: "", //提示文本
      alertShow: false //是否显示警告框
  }
}
methods: {
  //展示提示框
  showAlert(alertText) {
    this.alertShow = true;
    this.alertText = alertText;
  },
 //关闭警告框
  closeTip() {
    this.alertShow = false;
    this.alertText = '';
  },
  //异步登录
  login() {
    //前台表单验证
    if (this.loginWay) {
      //短信登录
      const { phone, code } = this;
      if (!this.rightPhone) {
        //手机号不正确
        this.showAlert("手机号不正确");
      } else if (!/^\d{6}$/.test(code)) {
        alert(this.code)
        //验证码必须是6位数字
        this.showAlert("验证码必须是6位数字");
      }
    } else {
      //密码登录
      const { name, pwd, captcha } = this;
      if (!this.name) {
        //用户名必须指定
        this.showAlert("用户名必须指定");
      } else if (!this.pwd) {
        //密码必须指定
        this.showAlert("密码必须指定");
      } else if (!this.captcha) {
        //图形验证码必须指定
        this.showAlert("图形验证码必须指定");
      }
    }
  }  
}
前台验证提示

三、前后台交互相关问题

  1. 如何查看你的应用是否发送某个ajax请求?
    • 浏览器的network


      查看network
  2. 发ajax请求404怎么办
    • 查看请求路径的对错
    • 单利是否生效(配置和重启)
    • 服务器应用是否运行
  3. 后台返回了数据,但页面没有显示?
    • vuex中是否有数据
    • 组件是否读取了数据
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343