封装Vuex的登录Action并处理token
建立登录接口
export function postLogin(data) {
return request({
url: '/sys/login',
method: 'post',
data
})
}
封装Vuex的登录Action
store/modules/user.js
const actions = {
// 登录
async login(context, loginForm) {
const res = await postLogin(
loginForm
)
console.log(res.token)
}
}
处理登录事件 views/login/index.vue
有需求可以使用 sha256 加密
安装依赖
cnpm install --save jssha@2.4.1
导入组件
const JsSHA = require('jssha')
使用jshsa
通过dispatch() 携带参数调用vuex里登录接口
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true
// 密码加密
const shaObj = new JsSHA('SHA-256', 'TEXT', { encoding: 'UTF8' })
shaObj.update(this.loginForm.password)
this.loginForm.password = shaObj.getHash('HEX')
// 调用登录接口
this.$store
.dispatch('user/login', this.loginForm)
.then(() => {
this.$router.push('/')
this.$message({
message: '登录成功',
type: 'success'
})
})
.catch(() => { })
.finally(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
在本地存储空间中保存token
在utils/uath.js封装三个方法
const TokenKey = 'vue_admin_template_token'
// 取token
export function getToken() {
return window.localStorage.getItem(TokenKey) || ''
}
// 设置token
export function setToken(token) {
return window.localStorage.setItem(TokenKey, token)
}
// 删token
export function removeToken() {
return window.localStorage.removeItem(TokenKey)
}
回到vuex中
导入
import { getToken, setToken, removeToken } from '@/utils/auth'
初始化token状态
const state = () => {
return {
token: getToken() // 设置token初始状态
}
}
设置token
const mutations = {
mutationSetToken(state, newToken) {
state.token = newToken // 设置token 只是修改state的数据
setToken(newToken) // vuex和 缓存数据的同步
}
}
让actions去修改state中的token,actions 修改state 必须通过mutations
const actions = {
// 登录
async login(context, loginForm) {
const res = await postLogin(
loginForm
)
console.log(res.token)
// actions 修改state 必须通过mutations
context.commit('mutationSetToken', res.token)
}
}
设置axios拦截器
import axios from 'axios'
import { Message } from 'element-ui'
// import store from '@/store'
// 创建了 axios 的实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000 // 请求超时
})
// 请求拦截器
service.interceptors.request.use(
config => {
// 在发送请求之前做一些事情
if (store.getters.token) {
// 把Token 放入请求头里
config.headers.Authorization = `Bearer ${state.user.token}`
}
return config
},
error => {
// 处理请求错误
console.log(error)
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
const res = response.data
// 当前请求成功 响应是失败
if (!res.success) {
Message({
message: res.message,
type: 'error'
})
// reject表示当前请求错误
return Promise.reject(new Error(res.message))
}
return res
},
error => {
console.log('err' + error)
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
建立路由守卫
/permission.js
import router from './router' // 引入路由实例
import store from './store' // 引入vuex store实例
// 白名单
const whiteList = ['/login', '/404']
// 路由前置守卫
// to:要进入的路由
// from:从回那个路由来
// next:是否允许进入
router.beforeEach((to, from, next) => {
// 判断用户是否登录
if (store.getters.token) {
next()
} else {
// 判断即将进入的页面是否在白名单里
if (whiteList.includes(to.path)) {
return next()
} else {
// 没登录,也没再白名单里,那么进入登录页面
next('/login')
}
}
})
// 后置守卫
router.afterEach(route => {
})
在 "src/main.js" 文件中导入 "permission.js":
import './permission'
退出登录
在actions里 清除token 回到登录页面
导入router
import router from '@/router'
// 退出登录
logout(context) {
// 清除 token
context.commit('mutationSetToken', '')
// 返回登录页
router.push('/login')
}
点击退出登录去触发actions里面的logout
async logout() {
await this.$store.dispatch('user/logout')
}