前端之登录逻辑

目录

1.创建表单

2.表单验证   

3.登录请求

4.封装登录请求动作

5.创建响应拦截器

6.登录权限

7.导航守卫


1.创建表单

<template>
  <div class="login-container">
    <el-form
      class="login-form"
      ref="loginFormRef"
      :model="loginForm"
      :rules="loginRules"
    >
      <div class="title-container">
        <h3 class="title">用户登陆</h3>
      </div>
      <!-- mobile  -->
      <el-form-item prop="mobile">
        <span class="svg-container">
          <svg-icon icon="user"></svg-icon>
        </span>
        <el-input
          placeholder="mobile"
          name="mobile"
          type="text"
          v-model="loginForm.mobile"
        ></el-input>
      </el-form-item>
      <!-- password  -->
      <el-form-item prop="password">
        <span class="svg-container">
          <svg-icon icon="password"></svg-icon>
        </span>
        <el-input
          placeholder="password"
          name="password"
          :type="passwordType"
          v-model="loginForm.password"
        ></el-input>
        <span class="show-pwd">
          <span class="svg-container" @click="onChangePwdType">
            <svg-icon
              :icon="passwordType === 'password' ? 'eye' : 'eye-open'"
            ></svg-icon>
          </span>
        </span>
      </el-form-item>
      <!-- 登陆按钮 -->
      <el-button
        type="primary"
        style="width: 100%; margin-bottom: 30px"
        :loading="loading"
        @click="handlerLogin"
      >
        登陆
      </el-button>
    </el-form>
  </div>
</template>

2.表单验证   

/**
 * 校验手机号  /utils/validate
 * ***/
export function validMobile(str) {
  return /^1[3-9]\d{9}$/.test(str)
}


import { validMobile } from '@/utils/validate'
export default {
  data() {
    const validateMobile = (rule, value, callback) => {
      validMobile(value) ? callback() : callback(new Error('手机号格式不正确'))
    }
    return {
      loginForm: {
        mobile: '13800000002',
        password: '123456'
      },
      loginRules: {
        // trigger 校验的触发方式 blur/change
        // 自定义函数
        mobile: [{ required: true, trigger: 'blur', message: '手机号不能为空' }, {
          validator: validateMobile, trigger: 'blur'
        }],
        password: [{ required: true, trigger: 'blur', message: '密码不能为空' }, {
          trigger: 'blur', min: 6, max: 16, message: '密码长度为6-16位之间'
        }]
      },
      loading: false,
    }
  },

3.登录请求

/** *
 * 登陆接口封装   /api/user
 * **/
export function login(data) {
// 返回一个promise对象
  return request({
    url: '/xxxxxx',
    method: 'post',
    data
  })
}



   //utils/auth
import Cookies from 'js-cookie'
export function getToken() {
  return Cookies.get(TokenKey)
}


import { getToken} from '@/utils/auth'
import { login } from '@/api/user'

// 状态
const state = {
  token: getToken(), // 设置token为共享状态 初始化vuex的时候 就先从缓存中读取
  userInfo: {} // 这里定义一个空对象 为什么要定义空对象
}
const mutations = {
  setToken(state, token) {
    state.token = token // 将数据设置给vuex
    // 同步给缓存
    setToken(token)
  }
}
const actions = {
  async login(context, data) {
    // 调用api接口
    const result = await login(data) // 拿到token
    context.commit('setToken', result) // 设置token
  }
}
export default {
  namespaced: true,
  state,
  mutations,
  actions
}

4.封装登录请求动作

methods: {
    ...mapActions(['user/login']), // 引入方法
    handleLogin() {
      // 表单的手动校验
      this.$refs.loginForm.validate(async isOK => {
        if (isOK) {
          try {
            this.loading = true
            // 只有校验通过了 我们才去调用action
            await this['user/login'](this.loginForm)
            // 应该登录成功之后
            // async标记的函数实际上一个promise对象
            // await下面的代码 都是成功执行的代码
            this.$router.push('/')
          } catch (error) {
            console.log(error)
          } finally {
            //  不论执行try 还是catch  都去关闭转圈
            this.loading = false
          }
        }
      })
    }
  }
}

5.创建响应拦截器

import axios from 'axios'
import { ElMessage } from 'element-plus'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000
})

// 响应拦截器
service.interceptors.response.use(
  // 请求成功
  (response) => {
    const data = response.data

    // 需要判断当前请求是否成功
    if (data != null) {
      // 成功返回解析后的数据
      const message1 = '-登陆成功-'
      ElMessage.success(message1)
      return data
    } else {
      // 失败(请求成功,业务失败) 消息提示
      const message1 = '-请求成功,业务失败-'
      ElMessage.error(message1)
      return Promise.reject(new Error(message1))
    }
  },
  // 请求失败
  (error) => {
    const message2 = '-请求失败-'
    ElMessage.error(message2)
    return Promise.reject(error)
  }
)

export default service

6.登录权限

import { createRouter, createWebHashHistory } from 'vue-router'

const Routes = [
  {
    path: '/login',
    component: () => import('@/views/login/index')
  },
  {
    path: '/',
    component: () => import('@/layout/index')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes: Routes
})

export default router

7.导航守卫

import router from '@/router'
import store from '@/store'

// 白名单
const whileList = ['/login']
router.beforeEach((to, from, next) => {
  if (store.getters.token) {
    if (to.path === '/login') {
      next('/')
    } else {
      next()
    }
  } else {
    if (whileList.indexOf(to.path) > -1) {
      next()
    } else {
      next('/login')
    }
  }
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值