发布时间:2023-03-03 11:30
├── dist // 打包构建后的文件夹
├── node_modules //该项目依赖的模块
├── public //存放静态资源(不会变动)
├── src
│ ├── assets //存放css、图片与js文件
│ │ ├── css
│ │ ├── img
│ │ └── js
│ ├── components //存放可复用的小组件
│ ├── http // 封装fetch、post请求及http 拦截器配置文件
│ │ ├── api.js
│ │ └── axios.js
│ ├── router //路由配置文件
│ │ └── index.js
│ ├── store //vuex
│ │ └── index.js
│ ├── views //存放主要页面(不可复用的页面组件)
│ ├── App.vue
│ └── main.js
├── .gitignore
├── babel.config.js
├── package-lock.json
├── package.json
├── README.md
└── vue.config.js
首先定义在路由配置文件多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录。如果用户已经登录,就顺利进入路由,否则就进入登录页面。
// src/router/index.js
const routes = [
{
path: \'/home\',
name: \'/home\',
component: () => import(\'../views/home/home.vue\')
},
{
path: \'/user\',
name: \'user\',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: () => import(\'../views/user/user.vue\')
},
{
path: \'/login\',
name: \'login\',
component: () => import(\'../views/login/login.vue\')
}
];
vue-router提供的钩子函数beforeEach()
对路由进行判断。
//src/router/index.js
//根据我们的项目需求
router.beforeEach((to,from,next)=>{
if(to.meta.requireAuth){ // 判断该路由是否需要登录权限
if(localStorage.getItem(\"access_token\")) { // 从本地存储localStorage获取当前的token是否存在
next()
}else{
next(\'/home\') //如果token不存在,就跳到首页
}
}else{
if(localStorage.getItem(\"access_token\") && to.path == \'/login\') { //token存在时候,进去登录页面就自动跳转到首页
next(\'/home\')
}else{
next()
}
}
});
完整的代码,如下:
import Vue from \'vue\'
import VueRouter from \'vue-router\'
Vue.use(VueRouter)
const routes = [
{
path: \'/home\',
name: \'/home\',
component: () => import(\'../views/home/home.vue\')
},
{
path: \'/user\',
name: \'user\',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: () => import(\'../views/user/user.vue\')
},
{
path: \'/login\',
name: \'login\',
component: () => import(\'../views/login/login.vue\')
}
];
const router = new VueRouter({
// mode: \'history\',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to,from,next)=>{
if(to.meta.requireAuth){ // 判断该路由是否需要登录权限
if(localStorage.getItem(\"access_token\")) { // 从本地存储localStorage获取当前的token是否存在
next()
}else{
next(\'/home\') //如果token不存在,就跳到首页
}
}else{
if(localStorage.getItem(\"access_token\") && to.path == \'/login\') { //token存在时候,进去登录页面就自动跳转到首页
next(\'/home\')
}else{
next()
}
}
});
export default router
使用axios的拦截器,统一处理所有http请求和响应。根据我们的项目需求,配合后台接口返回账号被迫下线或者返回401 Unauthorized(未授权),让用户重新登陆。
// src/http/axios.js
import axios from \'axios\'
import { Modal, message } from \'ant-design-vue\'
import router from \'@/router\'
axios.defaults.timeout = 10000 // 请求超时时间
const Service = axios.create({
baseURL: \'/\',
})
// axios 请求拦截器
Service.interceptors.request.use(
config=>{
if(localStorage.getItem(\"access_token\")){
config.headers.Authorization = \'Bearer\' + \' \' + localStorage.getItem(\'access_token\');
}
return config
},error=>{
Modal.confirm({
title: \'提示\',
content: \'请求超时!\',
});
return Promise.reject(error)
}
)
//有的一个页面请求几个接口,当token过期或者账号被迫下线,避免出现多个弹窗,自定义cont,判断cont==0时候弹窗一次,然后cont++
let cont = 0
// axios respone拦截器
Service.interceptors.response.use(
res=>{
if(res.status == 200){
if(res.data.message && res.data.message.type == \'logout\'){
if(cont == 0){
Modal.info({
title: \'信息\',
content: \"你的账号在别处登陆,请注意!\",
onOk() {
cont = 0
}
})
localStorage.removeItem(\'access_token\');
localStorage.removeItem(\'expires_time\');
if(router.history.current.path != \'/home\'){
router.push(\'/home\');
}
}
cont ++;
}
return res;
}else if (res.status == 401){
router.push(\'/home\');
return res;
}else if (res.status == 201) {
return res;
}
return res;
},
error=>{
const responseCode = error.response.status;
switch (responseCode) {
case 400:
message.error(\'请求错误(400)\')
break
case 401:
if(cont == 0) {
message.error(\'登录过期,请重新登录\')
}
cont++
llocalStorage.removeItem(\'access_token\');
localStorage.removeItem(\'expires_time\');
if(router.history.current.path != \'/home\'){
router.push(\'/home\');
}
break
case 403:
message.error(\'拒绝访问(403)\')
break
case 404:
message.error(\'请求出错(404)\')
break
case 408:
message.error(\'请求超时(408)\')
break
case 500:
message.error(\'服务器错误(500)\')
break
case 501:
message.error(\'服务未实现(501)\')
break
case 502:
message.error(\'网络错误(502)\')
break
case 503:
message.error(\'服务不可用(503)\')
break
case 504:
message.error(\'网络超时(504)\')
break
case 505:
message.error(\'HTTP版本不受支持(505)\')
break
default:
Modal.confirm({
title: \'提示\',
content: `连接出错(${error.response.status})!`,
});
}
return Promise.reject(error.response.data)
}
)
export default Service;
// src/http/api.js
import Service from \'./axios.js\'
// 登录
export const loginApi = data => {
return Service({
url: \'/api/authorizations\',
method: \'post\',
data
})
};
// 用户信息
export const userApi = data => {
return Service({
url: \'/api/user\' + data,
method: \'get\',
})
}
很简单,只需要从本地存储localStorage中当前token清除,再跳转到首页即可。
本文章根据我们的项目需求,作为个人思路笔记,仅供参考。