跨域问题之手机号码登录验证

15 篇文章 0 订阅

1. 构建登录组件

router.js:设置路由

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'index',
      component: () => import('./views/index.vue')
    },
    {
      path: '/login',
      name: 'login',
      component: () => import('./views/Login.vue')
    }
  ]
});

//路由守卫
router.beforeEach((to, from, next) => {
  const isLogin = localStorage.ele_login ? true : false;
  if (to.path == "/login") {
    next();
  } else {
    //是否在登录状态
    isLogin ? next() : next('/login')
  }
})

export default router;

2. 展示登录页面

组件的封装:

InputGroup.vue:

< template >
  <div id="text_group">
    <!-- 组件结构 -->
<!-- 组件容器 -->
<div class="input_group">
      <!-- 输入框 -->
<!-- @input="$emit(...)":获取input里面的值 -->
<!-- @input是用来定义输入的,是接收其他组件传过来的数据的 -->
<!-- 父组件可以使用props把数据传给子组件 -->
<!-- 子组件可以使用$emit触发父组件的自定义事件 -->
<input : type="type" :value="value" :placeholder="placeholder" :name="name" @input="$emit('input',$event.target.value)">
<!-- 输入框后面的按钮 -->
<button v-if="btnTitle" : disabled="disabled" @click="$emit('btnClick')">{{ btnTitle }}</button>
    <!-- 错误提醒 -->
<div v-if="error" class="invalid-feedback">{{ error }}</div>
  </div>
</div >
</template >

  <script>
    export default {
      name: "inputGroup",
  //props:需要使用该组件时传递的参数
props:{
      //type:输入内容的类型
      type: {
      type: String,
  default:"text"
  },
  //value:输入框里的值
  value:String,
  placeholder:String,
  name:String,
  btnTitle:String,
  disabled:Boolean,
  error:String
  }
  }
</script>

  <style scoped>
    .input_group {
      border: 1px solid #ccc;
  border-radius: 4px;
  padding: 10px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  }
.input_group input {
      height: 100%;
  width: 60%;
  outline: none;
  }
.input_group button {
      border: none;
  outline: none;
  background: #fff;
  }
.input_group button[disabled] {
      color: #aaa;
  }
.is-invalid {
      border: 1px solid red;
  }
.invalid-feedback {
      color: red;
  padding-top: 5px;
  }
</style>

Login.vue:

Login.vue:

<template>
  <div class="login">
    <div class="logo">
      <img src="../assets/logo.jpg" alt="my login image">
    </div>
    <!-- 手机号 -->
    <InputGroup
      type="number"
      v-model="phone"
      placeholder="手机号"
      :btnTitle="btnTitle"
      :disabled="disabled"
      :error="errors.phone"
      @btnClick="getVerifyCode"
    />
    <!-- 验证码 -->
    <InputGroup type="number" v-model="verifyCode" placeholder="验证码" :error="errors.code"/>

    <!-- 用户服务协议 -->
    <div class="login_des">
      <p>
        新用户登录即自动注册,表示已同意
        <span>《用户服务协议》</span>
      </p>
    </div>
    <!-- 登录按钮 -->
    <div class="login_btn">
      <button :disabled="isClick" @click="handleLogin">登录</button>
    </div>
  </div>
</template>
<script>
import InputGroup from "../components/InputGroup";
export default {
  name: "login",
  data() {
    return {
      phone: "",
      verifyCode: "",
      errors: {},
      btnTitle: "获取验证码",
      disabled: false
    };
  },
components: {
    InputGroup
  }
};
</script>

<style scoped>
.login {
  width: 100%;
  height: 100%;
  padding: 30px;
  box-sizing: border-box;
  background: #fff;
}

.logo {
  text-align: center;
}
.logo img {
  width: 150px;
}
.text_group,
.login_des,
.login_btn {
  margin-top: 20px;
}
.login_des {
  color: #aaa;
  line-height: 22px;
}
.login_des span {
  color: #4d90fe;
}
.login_btn button {
  width: 100%;
  height: 40px;
  background-color: #48ca38;
  border-radius: 4px;
  color: white;
  font-size: 14px;
  border: none;
  outline: none;
}
.login_btn button[disabled] {
  background-color: #8bda81;
}
</style>

3. 验证码倒计时

Login.vue:

methods: {
  getVerifyCode() {
    //先判断手机号码是否合法
    if (this.validatePhone()) {
      this.validateBtn();
    },
    //验证码倒计时
    validateBtn() {
      let time = 60;
      let timer = setInterval(() => {
        //当time=0时,清除clearInterval
        if (time == 0) {
          clearInterval(timer);
          this.btnTitle = "获取验证码";
          //当还没有获取验证码时,是能点击的
          this.disabled = false;
        } else {
          // 倒计时
          this.btnTitle = time + "秒后重试";
          //当正在获取验证码时,不能点击
          this.disabled = true;
          time--;
        }
      }, 1000);
    },
    // 验证手机号码
    validatePhone() {
      //手机号码为空时
      if (!this.phone) {
        this.errors = {
          phone: "手机号码不能为空"
        };
        return false;
      } else if (!/^1[345678]\d{9}$/.test(this.phone)) {
        this.errors = {
          phone: "请填写正确的手机号码"
        };
        return false;
      } else { //如果手机号码没有问题
        this.errors = {};
        return true;
      }
    }
  },

4. 获取短信验证码

聚合数据短信API

安装axios,然后可以发送请求了。

main.js:

import axios from 'axios'
Vue.prototype.$axios=axios

调用已经写好的接口,在根路径下创建vue.config.js:

module.exports = {
  devServer: {
    open: true,
    host: 'localhost',
    port: 8081,
    https: false,
    hotOnly: false,
    proxy: {
      // 配置跨域
      '/api': {
        target: 'https://ele-interface.herokuapp.com/api/',
        ws: true,
        changOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    },
    before: app => { }
  }
};

重启一次,用axios请求数据:需要用到短信API的key(短信模板配置申请通过后会生成)以及API的AppKey

getVerifyCode() {
  //先判断手机号码是否合法
  if (this.validatePhone()) {
    this.validateBtn();
    // 发送网络请求
    //"/api"就是vue.config.js中的url
    this.$axios.post("/api/posts/sms_send", {
      //传递我们所需要的内容
      tpl_id: "申请成功后的key",
      key: "短信API的AppKey",
      phone: this.phone
    })
      .then(res => {
        console.log(res);
      })
  }
},

5. 检验手机号码和验证


methods: {
  handleLogin() {
    // 取消错误提醒
    this.errors = {};
    // 发送请求
    this.$axios
      .post("/api/posts/sms_back", {
        phone: this.phone,
        code: this.verifyCode
      })
      .then(res => {
        // console.log(res);
        // 检验成功 设置登录状态并且跳转到/
        localStorage.setItem("ele_login", true);
        this.$router.push("/");
      })
      .catch(err => {
        // 返回错误信息
        this.errors = {
          code: err.response.data.msg
        };
      });
  },
}

 这样则表示发送验证码成功

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值