Vue element-ui - 登录的背后逻辑

登录业务流程:在登录页面输入用户名和密码,调用后台接口进行验证,通过验证之后,根据后台响应的状态跳转到项目主页
登录业务的相关技术点

  • 1.http是无状态的
  • 2.通过cookie在客户端记录状态,通过session在服务端记录状态(用户用账号和密码登录成功以后,后端php,java等,就会返回给一个 sessionId的值,存在数据库redis里面, 然后再通过一些 set-cookie响应头 发送给前端, 浏览器就会自动将这个值保存在用户电脑上面,称为cookie; 然后我们所有的请求发送之前 都会自动带上cookie这个参数放在请求头里面; 因为以前的haulcookie因为不能跨域,所以现在使用比较流行的token方式)
  • 3.通过token方式维持状态

token原理:用户在客户端登录页面输入用户名和密码进行登录,服务器验证通过之后生成该用户的token并返回,客户端收到服务器返回的token将它存储起来,后续客户端的所有请求都携带该token发送请求,服务器验证token是否通过。

登录的背后:
在这里插入图片描述
login页面的逻辑demo:

<script>
import asyncErrorHandler from '@/utils/asyncErrorHandler'
import { login } from '@/users/user'
import '@/store/index'

export default {
  name: 'login',
  data() {
    return {
      form: {
        name: '13811111111',
        password: '246810'
      },
      rules: {
        name: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 2, max: 15, message: '用户名格式不正确,请重新输入', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 3, max: 6, message: '密码格式不正确,请重新输入', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    async LoginSubmitForm() {
      this.$refs.LoginForm.validate((a, b) => {
        // console.log(a, b)
        if (!a) return this.$message.error('格式不正确,请重新输入!')
      })
      // 发送登录请求
      const [err, res] = await asyncErrorHandler(
        login({
          mobile: this.name,
          code: this.password
        })
      )
      this.$refs.LoginForm.resetFields()
      // 存储token在vuex
      this.$store.commit('setToken', res.data)
      // 跳转
      this.$router.push('/home')
    }
  }
}
</script>

import asyncErrorHandler from '@/utils/asyncErrorHandler'里面的asyncErrorHandler错误处理:

// 这个函数专门来处理 程序里大量的try...catch错误处理
// 在写返回值的时候,要按照node.js里面的error first原理,错误对象有限的手段,把错误对象放在第一位
export default function(promise) {
  return promise
    .then((res) => {
      return [null, res]
    })
    .catch((err) => {
      if (err.response && err.response.status === 400) {
        this.$message({
          duration: 1000,
          message: 'xxx错误',
          type: 'error'
        })
        return [err, null]
      } else if (err.response && err.response.status === 404) {
        this.$message({
          duration: 1000,
          message: 'xxx错误',
          type: 'error'
        })
        return [err, null]
      }
    })
}

import { login } from '@/users/user'里面的login:

import request from '@/utils/request'
import config from '@/config/url.config'

// 登录请求
export const login = function(data) {
  return request({
    url: config.login,
    method: 'post',
    data
  })
}

export default { login }

import config from '@/config/url.config'里面的代码:

export default {
  token: 'USER_TOKEN',
  baseURL: 'http://ttapi.research.itcast.cn/app/',
  // 登录
  login: 'v1_0/authorizations'
  //  还可以写接口.....
}

import request from '@/utils/request' 的代码:

import axios from 'axios'
import config from '@/config/url.config'
import { getItem, setItem } from '@/utils/storage'

const request = axios.create({
  baseURL: config.baseURL
})

// 路由白名单
const whiteList = ['login']

// 添加请求拦截器
request.interceptors.request.use(
  function(conf) {
    // 在发送请求之前做些什么
    // 判断用户是否登录并且有token值,有的话发请求携带上
    if (!whiteList.includes(conf.rul) && getItem(config.token)) {
      // 携带请求头 本地存储键值对的对象,而这里需要拼接token只
      conf.headers.Authorization = `${getItem(config.token).token}`
    }
    return conf
  },
  function(error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
request.interceptors.response.use(
  function(response) {
    // 对响应数据做点什么
    return response
  },
  function(error) {
    // 对响应错误做点什么
    return Promise.reject(error)
  }
)
export default request

import '@/store/index'里面的代码:

import Vue from 'vue'
import Vuex from 'vuex'
import { getItem, setItem } from '../utils/storage'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    token: getItem()
  },
  mutations: {
    setToken(state, payload) {
      state.token = payload
      setItem(payload)
    }
  },
  actions: {},
  modules: {}
})

import { getItem, setItem } from '../utils/storage'的代码:

// 本地持久化token
import config from '@/config/url.config'

export const setItem = function(data) {
  let tmp = ''
  if (typeof data === 'object') {
    tmp = JSON.stringify(data)
  }
  window.localStorage.setItem(config.token, tmp)
}

export const getItem = function() {
  const tmp = window.localStorage.getItem(config.token)
    ? window.localStorage.getItem(config.token)
    : null
  return tmp ? JSON.parse(tmp) : null
}

路由守卫代码:

import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入 getItem 持久化方法
import { getItem } from '@/utils/storage'
// 导入config 获取本地存储的名称
import config from '../config/url.config'

Vue.use(VueRouter)

const routes = [
  // 定义路由规则
  { path: '/', redirect: '/login' }, // 重定向
  {
    path: '/login',
    name: 'Login',
    component: () => import('@/views/login.vue')
  },
  {
    path: '/home',
    name: 'Home',
    component: () => import('../views/home')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})
// 设置路由守卫,用户必须登录才可以
router.beforeEach((to, from, next) => {
  // 每次跳转路由之前,都需要判断有没有登录,如果没有登录强制跳转到登录页面
  const tokenStr = getItem(config.token)
  // 如果是从登陆页面跳转过来的,直接放行,因为用户已经登录过了
  if (to.path === '/login') return next()
  // 如果本地无法获取token值,那么用户不能通过直接输入路由地址进行跳转,强行让用户进入登录界面
  if (!tokenStr) return next('/login')
  // 如果用户已经登录 代表有权限可以自由跳转所有的路由
  next()
})

export default router

登录背后的总结:

  • 请求可以拆分成模块化来写,1.把错误进行捕获 提示用户(错误处理封装);2.基础url、接口进行封装到一个文件(url.config.js)3.所有的请求也封装起来写(user.js)
  • 导航守卫,有些页面只有登录了才有权限去访问,有些页面不需要登录就可以访问,不需要登录就可以访问的就是路由白名单
  • 登录请求成功之后,把token在vuex进行数据储存,以及本地数据持久化(utils/storage.js)
  • 在请求拦截器里把需要权限才能访问的页面,添加token属性到Authrization字段,在拦截器里进行所需要校验的页面,完成筛选校验(utils/request.js)
  • 登录成功以后,根据服务器返回的数据,动态添加路由;不同角色有不同的权限,不同角色登录进去,返回的数据和看到的页面是不一样的
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当然可以!下面是一个简单的VueElement-UI实现的登录注册页面的代码示例: ```html <template> <div class="login-register"> <el-form ref="loginForm" :model="loginForm" label-width="80px"> <el-form-item label="用户名"> <el-input v-model="loginForm.username"></el-input> </el-form-item> <el-form-item label="密码"> <el-input type="password" v-model="loginForm.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="login">登录</el-button> </el-form-item> </el-form> <el-form ref="registerForm" :model="registerForm" label-width="80px"> <el-form-item label="用户名"> <el-input v-model="registerForm.username"></el-input> </el-form-item> <el-form-item label="密码"> <el-input type="password" v-model="registerForm.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="register">注册</el-button> </el-form-item> </el-form> </div> </template> <script> export default { data() { return { loginForm: { username: '', password: '' }, registerForm: { username: '', password: '' } }; }, methods: { login() { // 处理登录逻辑 }, register() { // 处理注册逻辑 } } }; </script> <style scoped> .login-register { width: 400px; margin: 0 auto; padding-top: 100px; } </style> ``` 这段代码实现了一个简单的登录注册页面,使用了VueElement-UI库。其中,`loginForm`和`registerForm`分别是登录和注册表单的数据模型,通过`v-model`指令与输入框进行双向绑定。点击登录和注册按钮时,会触发对应的方法进行登录和注册逻辑处理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值