总结一下今天在项目中完成的功能

手机验证码登录功能

用到的前端技术:vue、vuex、axios,element-ui组件库
功能实现总体思路:
一. 用户在登录界面输入手机号,通过表单验证后,点击按钮获取验证码
二. 用户输入手机验证码,再次进行校验,然后点击登录按钮进行登录
三. 向后台发起数据请求,等待后台返回结果,这一步有两件事要做:
1.发请求之前,对axios进行封装,配置基础请求路径、请求时长、默认post请求头,设置请求响应拦截器
2.如果请求响应成功,对后台返回用户登录的token和用户信息进行存储(存到本地)
3.如果请求响应失败,提示错误信息
四.拿到数据之后,对数据进行页面渲染
五.退出登录,清除token和用户信息

一、用户在登录界面输入手机号,通过表单验证后,点击按钮获取验证码 二. 用户输入手机验证码,再次进行校验,然后点击登录按钮进行登录

  1. 登录界面使用element-ui的el-form表单校验
<el-form
    class="phone-form"
    ref="form"
    :model="form"
    label-position="left"
    size="small"
    :rules="rules"
  >
    <el-form-item
      prop="phoneNum"
    >
      <el-input
        size="small"
        placeholder="请输入手机号"
        v-model="form.phoneNum"
        class="input-with-select"
      >
        <el-select v-model="select" slot="prepend" placeholder="+86">
          <el-option label="+86" value="+86"></el-option>
          <el-option label="+40" value="+86"></el-option>
          <el-option label="+111" value="+86"></el-option>
        </el-select>
      </el-input>
    </el-form-item>
    <el-form-item
    prop="checkCode">
      <el-input
        class="check-code-box"
        size="small"
        v-model.number="form.checkCode"
        placeholder="请输入验证码"
      >
        <el-button size="small" slot="append" @click="handleCaptcha"
          >获取验证码</el-button
        >
      </el-input>
    </el-form-item>
    <el-form-item>
      <el-button class="custom-button" @click="onSubmit('form')" type="primary"
        >登录</el-button
      >
    </el-form-item>
  </el-form>
  1. 验证规则
data () {
    return {
      rules: {
        phoneNum: [
          { required: true, message: '手机号码不能为空哦!', trigger: 'blur' },
          { min: 11, message: '请输入11位手机号码', trigger: 'blur' }
        ],
        checkCode: [
          { required: true, message: '验证码不能为空哦!', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    // 验证手机格式
    validatePho (value, callback) {
      if (value.toString().length < 11) {
        callback(new Error('手机号输入不正确'))
      }
    }
  }
  1. 获取验证码
// 获取手机验证码
    handleCaptcha () {
      captcha(this.form.phoneNum)
    }

axios 登陆界面 axios登录验证_javascript

三. 向后台发起数据请求,等待后台返回结果 四.拿到数据之后,对数据进行页面渲染

  1. 发请求之前,对axios进行封装,配置基础请求路径、请求时长、默认post请求头,设置请求响应拦截器
import axios from 'axios'
import store from '@/store/index'
import { Loading } from 'element-ui'

// 对axios进行封装
const request = axios.create({
  baseURL: '/api',
  timeout: 10000
})
// 设置post请求默认请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// loading进度样式
const options = {
  lock: true,
  background: 'rgb(0, 0, 0, 0.8)',
  text: 'Loading'
}

// 在请求之前拦截
request.interceptors.request.use(
  function (config) {
    Loading.service(options)
    // 每次发送请求之前判断vuex中是否存在token
    // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
    // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
    const token = store.getters.getToken
    if (token) {
      // 已经登录成功,统一添加token
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  function (error) {
    if (error.response.status) {
      // 判断错误类型(状态码)
      switch (error.response.status) {
        // 401: 未登录
        // 未登录则跳转登录页面,并携带当前页面的路径
        // 在登录成功后返回当前页面,这一步需要在登录页操作。
        case 401:
          this.$message({
            type: 'info',
            customClass: 'model-message',
            iconClass: '1',
            message: '未登录'
          })
          break
        // 403 token过期
        // 登录过期对用户进行提示
        // 清除本地token和清空vuex中token对象
        case 403:
          this.$message({
            type: 'info',
            customClass: 'model-message',
            iconClass: '1',
            message: '未登录'
          })
          break
          // 404请求不存在
        case 404:
          this.$message({
            message: '网络请求不存在',
            duration: 1500,
            type: 'success'

          })
          break
        // 其他错误,直接抛出错误提示
        default:
          this.$message({
            message: error.response.data.message,
            duration: 1500,
            type: 'success'
          })
      }
      // 对请求错误进行操作
      return Promise.reject(error)
    }
  }
)

// 在请求之后拦截
request.interceptors.response.use(
  function (response) {
    if (response.status === 200) {
      // 对响应数据进行操作
      Loading.service(options).close()
      return Promise.resolve(response)
    } else {
      return Promise.reject(response)
    }
  },
  function (error) {
    // 对响应错误进行操作
    return Promise.reject(error)
  }
)

export default request
  1. 如果请求响应成功,对后台返回用户登录的token和用户信息进行存储,这里用vuex对token和用户信息进行管理,而且要进行持久化,不然页面一刷新数据就没有了
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

const state = {
  // 存储token
  token: '',
  // 当前用户基本信息
  userInfo: ''
}

const getters = {
  // 获取token
  getToken (state) {
    return state.token || localStorage.getItem('token') || ''
  }
}

const mutations = {
  // 设置token
  SETTOKEN (state, token) {
    state.token = token
    // 存储token
    localStorage.setItem('token', token)
  },
  // 删除token
  DELTOKEN (state) {
    state.token = ''
    localStorage.removeItem('token')
  },
  // 更新用户信息
  UPDATEUSERINFO (state, value) {
    state.userInfo = value
  },
  // 删除用户信息
  DELETEUSERINFO (state) {
    state.userInfo = ''
    localStorage.removeItem('userInfo')
  }
}

export default new Vuex.Store({
  // 本地缓存(持久化)PersistedState
  plugins: [createPersistedState({
    reducer: (state) => {
      return {
        songInfo: state.songInfo,
        songUrl: state.songUrl,
        model: state.model,
        renList: state.renList,
        songIndex: state.songIndex,
        userInfo: state.userInfo
      }
    }
  })],
  state,
  getters,
  mutations
})
  1. 在点击按钮的时候,进行整改表单的校验,如果校验成功,发送手机号和验证码给后台,如果请求响应失败,提示错误信息 (错误信息的提示我用到了element-ui的Message样式组件)
computed: {
    ...mapState({
      // 登录凭证
      token: 'token'
    })
},
methods: {
	...mapMutations({
      // 存储token
      setToken: 'SETTOKEN',
      // 更新用户信息
      updateUserInfo: 'UPDATEUSERINFO'
    }),
    // 手机验证码登录
    async onSubmit (form) {
      this.$refs[form].validate(async (valid) => {
        if (valid) {
          await cellphone(this.form.phoneNum, this.form.checkCode)
            .then(res => {
              console.log(res)
              // 存储token
              this.setToken(res.data.token)
              // 存储用户信息
              this.updateUserInfo(res.data.profile)
              this.$message({
                type: 'info',
                customClass: 'model-message',
                iconClass: '1',
                message: '登录成功'
              })
              // 通知父组件显示用户名
              this.$emit('isActive')
            })
            .catch(error => {
              this.$message({
                type: 'info',
                customClass: 'model-message',
                iconClass: '1',
                message: error
              })
            })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    }
}
  1. 渲染数据,用到了element-ui的下拉菜单组件、头像组件
<div class="container">
    <div class="login-box">
      <el-dropdown
        v-if="isActive"
        class="custom-el-dropdown"
        @command="handleCommand"
      >
        <span class="el-dropdown-link hidden-xs-only">
          <el-avatar v-if="userInfo" size="medium" :src="userInfo.avatarUrl"></el-avatar>
          <div class="nickname">{{ userInfo.nickname }}
            <i class="el-icon-arrow-down el-icon--right"></i>
          </div>
        </span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="mineHomepage">我的主页</el-dropdown-item>
          <el-dropdown-item command="minePlayList">我的歌单</el-dropdown-item>
          <el-dropdown-item command="logOut">退出登录</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <el-button
        v-else
        type="text"
        @click="handleDialogForm()"
        class="custom-login"
        >
          登录
        </el-button>
    </div>

五.退出登录,清除token和用户信息

// 下拉菜单事件
    async handleCommand (command) {
      switch (command) {
        // 退出登录
        case 'logOut':
          await logout()
            .then(res => {
              // 清除token
              this.delToken()
              // 清除用户信息
              this.deleteUserInfo()
              // 是否显示用户名
              this.handleUserName()
              this.$message({
                type: 'info',
                customClass: 'model-message',
                iconClass: '1',
                message: '注销成功'
              })
            })
            .catch(err => {
              console.log(err)
            })
          break
        // 获取我的歌单
        case 'minePlayList':
          this.minePlayList()
          break
        // 我的主页
        case 'mineHomepage':
          break
      }

登录成功效果:

axios 登陆界面 axios登录验证_javascript_02


这功能的实现离不开大佬的手把手教懂,通过学习大佬的下面的文章,我才能顺利完成我的功能。