PC项目登录登出功能-登录页/主页

该文描述了一个Vue.js应用中的登录模块实现,包括UI界面设计、手机号和密码验证、登录接口封装、Vuex状态管理和数据存储、以及token的获取、存储和过期处理。还涉及到了请求和响应拦截器的使用,以及路由守卫在权限控制中的应用。
摘要由CSDN通过智能技术生成

登录模块

设计UI结构,修改样式,UI结构中重点是登录表单验证。手机号和密码验证

<el-form

ref="loginForm"

:model="loginForm"

:rules="loginRules"

class="login-form"

auto-complete="on"

label-position="left"

>

<div class="title-container">

<h3 class="title">

<img

src="@/assets/common/login-logo.png"

alt=""

>

</h3>

</div>

<el-form-item prop="mobile">

<span class="svg-container">

<svg-icon icon-class="user" />

</span>

<el-input

v-model="loginForm.mobile"

placeholder="请输入手机号"

name="mobile"

type="text"

tabindex="1"

auto-complete="on"

/>

</el-form-item>

<el-form-item prop="password">

<span class="svg-container">

<svg-icon icon-class="password" />

</span>

<el-input

:key="passwordType"

ref="password"

v-model="loginForm.password"

:type="passwordType"

placeholder="请输入密码"

name="password"

tabindex="2"

auto-complete="on"

@keyup.enter.native="handleLogin"

@keyup.enter="submit"

/>

<span

class="show-pwd"

@click="showPwd"

>

<svg-icon

:icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"

/>

</span>

</el-form-item>

<el-button

class="loginBtn"

:loading="loading"

type="primary"

style="width:100%;margin-bottom:30px;"

@click.native.prevent="handleLogin"

@keyup.enter="submit"

>登录</el-button>

<div class="tips">

<span style="margin-right:20px;">账号:13800000002</span>

<span> 密码: 123456</span>

</div>

</el-form>

data () {

const validateMobile = (rule, value, callback) => {

validMobile(value) ? callback() : callback(new Error('手机号格式不正确'))

}

return {

loginForm: {

mobile: '13800000002',

password: '123456'

},

loginRules: {

mobile: [

{ required: true, trigger: 'blur', message: '手机号不能为空' },

{ validator: validateMobile, trigger: 'blur' }

],

password: [

{ required: true, trigger: 'blur', message: '密码不能为空' },

{ min: 6, max: 16, message: '密码的长度在6-16位之间', trigger: 'blur' }

]

},

loading: false,

passwordType: 'password',

redirect: undefined

}

},

methods: {

handleLogin () {

// 手动校验

this.$refs.loginForm.validate(async isOK => {

if (isOK) {

try {

this.loading = true

await this['user/login'](this.loginForm)

this.$router.push('/')

} catch (error) {

console.log(error)

} finally {

this.loading = false

}

}

})

}

}

封装登录的接口

使用Vuex来管理状态以及存储数据

封装一个工具用来存储token到cookies或localstorage

import Cookies from 'js-cookie'

const TokenKey = '###-###-key'

const timeKey = '###-###-key'

// 获取token

export function getToken () {

return Cookies.get(TokenKey)

}

// 获取时间戳

export function getTimeStamp () {

return Cookies.get(timeKey)

}

// 设置token

export function setToken (token) {

return Cookies.set(TokenKey, token)

}

// 设置时间戳

export function setTimeStamp () {

return Cookies.set(timeKey, Date.now())

}

// 删除token

export function removeToken () {

return Cookies.remove(TokenKey)

}

当token发生变化时就在store里管理

// 状态

// vuex的持久化 在utils工具中设定存储 可以用cookie、loadStorage等管理token,然后在vuex(store管理vuex)用时调出来用 可以进行状态设定存储 修改等操作(修改时有同步和异步) 每次修改后同步给缓存(也就是每次都存一下setToken)

const state = {

// 设置token共享状态(从本地获取)

token: getToken(),

userInfo: {} // 放一个空的对象,后面存放数据给别人用

}

// 修改状态

const mutations = {

// 设置和删除token

setToken (state, token) {

state.token = token // (每次操作后修改状态并存入)

// 同步给缓存

setToken(token) // vuex和 缓存数据的同步

},

removeToken (state) {

state.token = null // 删除vuex的token

removeToken() // 先清除 vuex 再清除缓存 vuex和 缓存数据的同步

},

// 设置和删除用户资料

setUserInfo (state, result) { // result为获取到的用户资料结果

state.userInfo = result

},

removeUserInfo (state) {

state.userInfo()

}

}

// 执行异步

// 获取登录信息也好,获取用户基本资料也好,只要是异步操作都在这里执行

const actions = { }

执行异步操作,调取接口,获取数据并存储Vuex中

第一次登录时,设置基础地址。

服务器响应拦截器工作,返回两个结果,响应和失败,响应了如果成功返回数据如果人为失败则new一个错误对象提示,失败则return失败的信息

// 响应拦截器

// 两个函数一个成功一个失败:请求成功则解构数据判断成功了拿数据失败了提示错误失败,或者一开始请求时就会失败

service.interceptors.response.use(response => {

const { success, message, data } = response.data

if (success) {

return data

} else {

// 业务错误 要进入catch,所以return

Message.error(message)

// 人为错误,故new一个错误对象

return Promise.reject(new Error(message))

}

}, error => {

//此处为token失效的被动处理,可忽略

if (error.response && error.response.data && error.response.data.code === 10002) {

store.dispatch('user/logout') // 执行登出操作 删除token数据

router.push('/login') // 路由跳转登录页面

//此处为token失效的被动处理,可忽略

} else {

Message.error(error.message)

}

return Promise.reject(error) // 返回错误,直接进入catch

})

此时当已经成功获取数据,并且在Vuex中存储。然后在页面中调取方法获取数据渲染。...mapActions([''])方式

此时完成登录页的数据渲染及跳转登录

主页

主页跳转时设个权限拦截(路由守卫)判断是否有token

const whiteList = ['/login', '/404'] // 定义白名单 所有不受权限控制的页面

// 路由前置守卫

router.beforeEach(async function (to, from, next) {

NProgress.start() // 开启进度条

// 权限拦截首先判断是否有token,是否是登陆页面,符合就跳转主页。或者是否在白名单也可直接跳转。否则跳回登录页

// 先判断是否有token

if (store.getters.token) {

// 如果有token继续判断是不是去登录页 是跳转主页 否放行等待处理

if (to.path === '/login') {

// 表示取得是登录页

next('/')

} else {

// 这是第二步,有token却不是登录页需要放行,此时也需要用户信息了

if (!store.getters.userId) {

await store.dispatch('user/getUserInfo') // 获取用户信息的

}

next() // 直接放行

}

} else {

// 如果未携带token

if (whiteList.indexOf(to.path) > -1) {

next()

} else {

// 跳回到登录页

next('/login')

}

}

// 手动关闭进度条

NProgress.done()

})

// 后置守卫

router.afterEach(function () {

NProgress.done()

})

主页页面布局部分(省略)

封装获取用户信息的接口

每次请求需携带token,故在请求拦截器处统一注入

我们仍然是异步获取数据Actions,然后将数据暂存Vuex

因为获取用户信息需要有token,所以可以在有token的地方设置路由权限(路由前置守卫在有token的情况下是否时登录页是的话跳转,不是的话路由守卫一下判断是否有用户信息,没有要及时await获取)获取信息

将获取到的用户信息数据渲染到页面中

实现登出,完成闭环

登出时仍可异步操作数据,删除token和用户信息,路由跳转页面

其中有一个问题即token失效(主动接入/被动处理)

设置一个时间戳

在登录时设置时间戳

在请求拦截器中有token的情况下检查时间戳是否超时

// 请求拦截器

service.interceptors.request.use(config => {

// 需要在每次访问时携带一个token,故而在这个位置统一去注入,省去很多麻烦

if (store.getters.token) {

// 只有在有token的情况下 才有必要去检查时间戳是否超时

if (IsCheckTimeOut()) { // 表示过期 跳回到登录页

store.dispatch('user/logout') // 登出操作

router.push('/login')

return Promise.reject(new Error('token超时了'))

}

config.headers['Authorization'] = `Bearer ${store.getters.token}`

}

return config

}, error => {

return Promise.reject(error)

})

// 定义一个判断超时的逻辑(当前时间-缓存时间)是否大于 时间差

function IsCheckTimeOut () {

const currentTime = Date.now() // 当前时间戳

const timeStamp = getTimeStamp() // 缓存时间戳

return (currentTime - timeStamp) / 1000 > TimeOut // 表示超时

}

时间戳可存入cookies,用时取,每次登录时存入一个时间戳

好了以上完结一个项目的登录功能。

总结一下:

PC项目登录登出功能全过程-登录页/主页

登录页:

UI静态页面设计、

css样式修改、

封装接口、

调取接口(异步执行action)、

响应拦截器拦截判断、

拿到数据暂存Vuex 在页面中调取Vuex中的数据渲染页面

主页:

跳转登录到主页后会加载数据,以及是否有token可以进行跳转,故可以设置权限拦截许可(路由守卫)前置守卫是否携带token。

成功跳转后需:

封装获取用户信息的接口、

铺设主页的静态页面及样式修改、

调取接口获取数据(action)异步执行(Vuex的作用1可以管理状态2则可以存储数据)、

发送请求时请求拦截器可以统一注入token以及携带请求头,因大多数请求需要token、封装一个存储数据的文件cookies存储,用户登录登出可存 取 删除数据。、

最后仍将暂存Vuex中的数据渲染到主页页面中、

权限拦截切记(路由守卫)一般放行后都应该有数据此时路由守卫在有token的时候就守卫判断一下。

最后就是token过期的主动介入和被动处理:

定义一个判断超时的逻辑,主动介入即在登陆时设置一个时间戳和获取当前时间戳,在请求拦截器中计算判断、被动处理即在响应拦截器判断token状态,过期后自动退出登录。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值