router\index.js
增加路由要放在详情路由前面
{
path: '/blog/add', // 注意放在 path: '/blog/:blogId'之前
name: 'BlogAdd',
meta: {
requireAuth: true
},
component: BlogEdit
},
{
path: '/blog/:blogId',
name: 'BlogDetail',
component: BlogDetail
},
{
path: '/blog/:blogId/edit',
name: 'BlogEdit',
meta: {
requireAuth: true
},
component: BlogEdit
}
带有meta:requireAuth: true说明是需要登录字后才能访问的受限资源,后面我们路由权限拦截时候会用到。
submitForm(formName) {
const _this = this
this.$refs[formName].validate((valid) => {
if (valid) {
// 提交逻辑
this.$axios.post('http://localhost:8081/login', this.ruleForm).then((res)=>{
const token = res.headers['authorization']
_this.$store.commit('SET_TOKEN', token)
_this.$store.commit('SET_USERINFO', res.data.data)
_this.$router.push("/blogs")
})
} else {
console.log('error submit!!');
return false;
}
});
},
从返回的结果请求头中获取到token的信息,然后使用store提交token和用户信息的状态。
token的状态同步
所以在store/index.js中,代码是这样的:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
token: '',
userInfo: JSON.parse(sessionStorage.getItem("userInfo"))
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
localStorage.setItem("token", token)
},
SET_USERINFO: (state, userInfo) => {
state.userInfo = userInfo
sessionStorage.setItem("userInfo", JSON.stringify(userInfo))
},
REMOVE_INFO: (state) => {
localStorage.setItem("token", '')
sessionStorage.setItem("userInfo", JSON.stringify(''))
state.userInfo = {}
}
},
getters: {
getUser: state => {
return state.userInfo
}
},
actions: {},
modules: {}
})
存储token,我们用的是localStorage,存储用户信息,我们用的是sessionStorage。毕竟用户信息我们不需要长久保存,保存了token信息,我们随时都可以初始化用户信息。
点击登录按钮发起登录请求,成功时候返回了数据,如果是密码错误,我们是不是也应该弹窗消息提示。为了让这个错误弹窗能运用到所有的地方,所以我对axios做了个后置拦截器,就是返回数据时候,如果结果的code或者status不正常,那么我对应弹窗提示。
在src目录下创建一个文件axios.js(与main.js同级),定义axios的拦截:
import axios from 'axios'
import Element from "element-ui";
import store from "./store";
import router from "./router";
axios.defaults.baseURL='http://localhost:8081'
axios.interceptors.request.use(config => {
console.log("前置拦截")
// 可以统一设置请求头
return config
})
axios.interceptors.response.use(response => {
const res = response.data;
console.log("后置拦截")
// 当结果的code是否为200的情况
if (res.code === 200) {
return response
} else {
// 弹窗异常信息
Element.Message({
message: response.data.msg,
type: 'error',
duration: 2 * 1000
})
// 直接拒绝往下面返回结果信息
return Promise.reject(response.data.msg)
}
},
error => {
console.log('err' + error)// for debug
if(error.response.data) {
error.message = error.response.data.msg
}
// 根据请求状态觉得是否登录或者提示其他
if (error.response.status === 401) {
store.commit('REMOVE_INFO');
router.push({
path: '/login'
});
error.message = '请重新登录';
}
if (error.response.status === 403) {
error.message = '权限不足,无法访问';
}
Element.Message({
message: error.message,
type: 'error',
duration: 3 * 1000
})
return Promise.reject(error)
})
然后再main.js中导入axios.js
import './axios.js' // 请求拦截
methods: {
logout() {
const _this = this
this.$axios.get('http://localhost:8081/logout', {
headers: {
"Authorization": localStorage.getItem("token")
}
}).then((res) => {
_this.$store.commit('REMOVE_INFO')
_this.$router.push('/login')
});
}
},