Vue2项目之移动端购物商城(二) 登录页的实现,vant组件Toast的使用,对axios进行二次封装,将数据的请求封装成api接口

发布于:2025-05-09 ⋅ 阅读:(15) ⋅ 点赞:(0)

零.前置相关内容

1.Toast组件的使用
使用场景

在用户输入手机号后,需要给出提示,若输入正确:“发送成功,请注意查收!”,
若输入不正确:“请输入正确的手机号”

使用步骤
  • Toast轻提示组件的注册安装,步骤略(同NavBar)
  • 使用方式1----导入调用(组件或非组件内都可以):Toast("提示内容")
  • 使用方式2----通过this直接调用(组件内):this.$toast("提示内容"),

这种方法的本质是把方法注册挂载到了Vue原型上:Vue.prototype.$toast=xxx

常用用法
  • 文字提示:Toast(‘提示内容’)
  • 加载提示:
 Toast.loading(){
    message:'加载中',
    forbidClick:true
}
  • 成功/失败提示:Toast.success和Toast.fail
2.为什么要对axios进行二次封装?

axios的二次封装

省流

使用axios请求后端接口,一般都会对axios进行一些配置,比如配置基础地址,请求&响应拦截器等
所以在项目开发中,都会对axios进行基本的二次封装,单独封装到一个request模块中,便于维护使用

步骤(以获取图形验证码为例)
  • 新建封装文件utils/request.js
import axios from 'axios'
const instance = axios.create({// 创建一个axios实例instance
  baseURL: 'http://smart-shop.itheima.net/index.php?s=/api', // 注意操作文档上的基础地址是否变动
  timeout: 1000
})
// 请求拦截器:发送请求之前做些什么
instance.interceptors.request.use(config => {
  return config// 成功的回调
}, error => {
  return Promise.reject(error)// 失败的回调
})
// 响应拦截器:接收返回数据之前做些什么
instance.interceptors.response.use(res => {
  return res.data// axios返回数据默认多包一层data,提前剥掉
}, err => {
  return Promise.reject(err)
})
// 导出实例
export default instance
  • 在页面中试调用(需提前查看阅读文档,获取请求方式,请求路径和请求参数)
    在这里插入图片描述
import request from '@/utils/request.js'
data () {
  return {
    picUrl: '',
    picKey: ''
  }
},
async created () {
   // const res = await request.get('/captcha/image')
    //console.log('获取到的数据:', res)//获取到data,message,status三个属性
    const { data: { base64, key } } = await request.get('/captcha/image') // 把需要的res对象解构出来
    this.picUrl = base64
    this.picKey = key
},
  • 用获取到的数据动态渲染登录页面:
<div class="form-item">
    <input type="text" class="inp" maxlength="5" placeholder="请输入图形验证码">
    <!-- <img src="https://img0.baidu.com/it/u=1838409809,2846524470&fm=253&fmt=auto&app=138&f=JPEG?w=443&h=236"> -->
    <img :src="picUrl">
</div>

在这里插入图片描述

3.为什么以及如何将请求封装成api接口?

在中大型项目中,最好把请求封装成方法,统一存放到api模块,与页面分离
这么做的理由是:
       在上例中,若在页面中类似的请求多了起来,整个页面会充斥着请求的代码,可阅读性较差,而且相同的请求也没有被复用,更没有被统一管理
统一放到api模块后:
       将实现请求和页面的分离,复用相同请求并对请求统一管理

步骤:(优化上例)

  • 新建请求模块并封装:把之前在页面中发送的请求放在新文件src/api/login.js中封装起来
import request from "@/utils/request"
export const getPicCode=()=>{//起一个方法名,以与后面同页面的其他请求做区分
   return request.get('/captcha/image');//必须要return,不然获取不到结果
}
  • 在页面中Login/index.js按需导入并调用
import { getPicCode } from '@/api/login.js'
async created () {
    const { data: { base64, key } } = await getPicCode()
    this.picUrl = base64
    this.picKey = key
  },
}
  • 优化:考虑到在created中将不止发送一次数据请求,可以把方法写在methods中然后再在created中调用
  import { getPicCode } from '@/api/login.js'
  created () {
    this.getPicCodeMethods()
  },
  methods: {
    async getPicCodeMethods () {
      const { data: { base64, key } } = await getPicCode()
      this.picUrl = base64
      this.picKey = key
    }
  },

一.登录页静态布局

0.login页分为上下两部分

上面–导航条:使用vant的NavBar作为通用组件,(在几乎每个页面都使用)
下面–主题部分:自定义

1.NavBar组件的使用
  • 在官网上查用法(属性和属性值)
  • 在utils/vant-ui.js中按需引入
import { NavBar } from 'vant'
Vue.use( NavBar )
  • 在Login页中使用
<van-nav-bar title="会员登录" left-arrow @click-left="$router.go(-1)" />
2.登录页主体部分
<template>
  <div class="login">
    <van-nav-bar title="会员登录" left-arrow @click-left="$router.go(-1)" />
    <div class="container">
      <div class="title">
        <h3>手机号注册</h3>
        <p>未注册的手机号登录后将自动注册</p>
      </div>
      <div class="form">
        <div class="form-item">
          <input type="text" class="inp" maxlength="11" placeholder="请输入手机号码">
          </div>
        <div class="form-item">
          <input type="text" class="inp" maxlength="5" placeholder="请输入图形验证码">
          <img src="https://img0.baidu.com/it/u=1838409809,2846524470&fm=253&fmt=auto&app=138&f=JPEG?w=443&h=236">
          </div>
        <div class="form-item">
          <input type="text" class="inp" maxlength="5" placeholder="请输入短信验证码">
          <button>获取验证码</button>
          </div>
      </div>
      <div class="login-btn">登录</div>
    </div>
  </div>
</template>

效果:
在这里插入图片描述

二.图片验证码相关功能

图片验证码的本质是后台返回的照片,目的是强制人和机器之间的交互,抵御自动化攻击(如:避免批量请求获取短信)

1.获取图片验证码

略,详见:3.为什么以及如何将请求封装成api接口?

2.对文本框输入的手机号码和图片验证码进行正则校验
//step1:分别在手机号和图形验证码的input框中,使用v-model双向绑定在data中声明的变量moblie和picCode
//step2:在函数isVaild中分别对两个变量进行正则校验,当它们格式错误时返回false
/*login/index.vue/methods*/
    isValid () { // 正则校验:手机号和图形验证码
      // 1.手机号的正则:以1开头,第2位3`9,一共11位数字
      if (!/^1[3-9]\d{9}$/.test(this.mobile)) {
        this.$toast('请输入正确的手机号!')
        return false
      }
      // 2.图形验证码的正则:4个字符
      if (!/^\w{4}/.test(this.picCode)) {
        this.$toast('请输入正确的图形验证码!')
        return false
      }
      // 其他情况则通过
      return true
    },
    //step3:调用isValid函数
    	//在哪里调用?==>点击发送短信,或点击登录按钮时调用(后续内容)

三.短信验证码相关功能

1.实现倒计时效果:点击"获取验证码",开始倒计时59s

业务要求:

  • 输入的手机号和图形验证码要正确
  • 1分钟内倒计时只会触发一次
  • 按钮的文字不是固定的,倒计时开始后变成"重新获取59s"
    思路:
    对"获取验证码"按钮绑定点击事件getCode,声明三个新变量totalSec,nowSec,timer,分别代表总秒数,当前秒数和定时器的名字
    当前timer定时器并未开启,且总秒数=当前秒数时,开启定时器
    让nowSec每秒自减,当它的值小于等于0时清空定时器并初始化变量
    // 点击开启倒计时
    getCode () {
      if(!this.isVaild()) return//手机号和图形验证码格式不对,不继续往下了
      if (!this.timer && this.totalSec === this.nowSec) {
        this.$toast('短信发送成功,请注意查收!')
        this.timer = setInterval(() => {// 1分钟内倒计时只会触发一次
          console.log(this.nowSec--)
          if (this.nowSec <= 0) {
            clearInterval(this.timer)
            this.timer = null
            this.nowSec = this.totalSec
          }
        }, 1000)
      }

优化:"获取验证码"按钮的文本从写死变成动态渲染

<button @click="getCode">{{this.nowSec==this.totalSec?'获取验证码':`重新获取${this.nowSec}`}}</button>

优化:为避免性能浪费,加入业务逻辑—当用户离开登录页时,关闭定时器

  destroyed () {
    clearInterval(this.timer)
  }
2.获取短信验证码
  • 查看接口文档,确定请求方式,请求路径,请求参数
    在这里插入图片描述在这里插入图片描述
  • 封装请求
//api/login.js
......
//获取短信验证码
export const getMsgCode=(captchaCode, captchaKey, mobile)=>{
	return request.post('/captcha/sendSmsCaptcha',{
		form:{
			captchaCode, //图形验证码
			captchaKey,	//图形验证码key
			 mobile	//手机号
		}
	)
}
  • 页面调用
import { getPicCode, getMsgCode } from '@/api/login.js'
...
methods:{
	async getMsgCodeMethods(){//在getCode方法中调用
		const res=await getMsgCode(this.picCode,this.picKey,this.mobile);
	}
}

. 在这里插入图片描述

四.登录相关功能


网站公告

今日签到

点亮在社区的每一天
去签到