vue登录拦截与请求/响应拦截

登录拦截

在路由文件 router.js 中引入 store.js

import store from '../store/store'

配置需要登录权限的路由

   {
            path: '/main',
            meta: {
                requireAuth: true // 添加该字段,表示进入这个路由是需要登录的
            },
            component: (resolve) => require(['../components/main'], resolve)
        },

在写好的路由下方加上判断该路由是否需要登录权限

 ...

 router.beforeEach((to, from, next) => {
  if (to.meta.requireAuth) {  // 判断该路由是否需要登录权限
    console.log('beforeEach获取当前的token是否存在  '+store.state.loginModule.token)
    if (store.state.loginModule.token) {  // 通过vuex state获取当前的token是否存在
      next();
    }
    else {
      next({
        path: '/login',
        query: {redirect: to.fullPath}  // 将跳转的路由path作为参数,登录成功后跳转到该路由
      })
    }
  }
  else {
    next();
  }
 });

请求/响应拦截

新建一个 http.js 文件

 import axios from 'axios'
 import store from './store/store'
 import * as types from './store/mutation_type'
 import router from './router/index'

 axios.defaults.timeout = 5000; // 超时时间
 //axios.defaults.baseURL = '';

 // http request 拦截器
 axios.interceptors.request.use(
    config => {
        if (store.state.token) {  // 判断是否存在token,如果存在的话,则每个http header都加上token
            config.headers.Authorization = `token ${store.state.loginModule.token}`;
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    });

 // http response 拦截器
 axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (error.response) {
            switch (error.response.status) {
                case 401:
                    // 401 清除token信息并跳转到登录页面
                    store.commit('loginOut');
                    router.replace({
                        path: 'login',
                        query: {redirect: router.currentRoute.fullPath}
                    })
            }
        }
        // console.log(JSON.stringify(error));//console : Error: Request failed with status code 402
        return Promise.reject(error.response.data)  // 返回接口返回的错误信息
    });

 export default axios;

然后在 main.js 文件中引入 http.js 文件

 import Vue from 'vue'
 import App from './App'
 import router from './router'
 import store from './store/store'
 import axios from './http'

 Vue.config.productionTip = false

 /* eslint-disable no-new */
 new Vue({
   el: '#app',
   router,
   store,
   axios,
   template: '<App/>',
   components: { App }
 })

如果项目使用的是element-ui, http.js文件可以这么写

// 引入axios以及element ui中的loading和message组件
  import axios from 'axios'
  import { Loading, Message } from 'element-ui'
  // 超时时间
  axios.defaults.timeout = 5000
  // http请求拦截器
  var loadinginstace
  axios.interceptors.request.use(config => {
    // element ui Loading方法
    loadinginstace = Loading.service({ fullscreen: true })
    return config
  }, error => {
    loadinginstace.close()
    Message.error({
      message: '加载超时'
    })
    return Promise.reject(error)
  })
  // http响应拦截器
  axios.interceptors.response.use(data => {// 响应成功关闭loading
    loadinginstace.close()
    return data
  }, error => {
    loadinginstace.close()
    Message.error({
      message: '加载失败'
    })
    return Promise.reject(error)
  })

  export default axios

vue 懒加载

     {
      path: '/login',
      component: (resolve) => require(['../components/login'], resolve)
     }

vue页面刷新后,信息为空

在路由文件 router.js 中引入 mutation_type 文件

  import * as type from '../store/mutation_type'

页面刷新时,重新赋值token

   // 页面刷新时,重新赋值token
  if (window.localStorage.getItem('token')) {
    store.commit('loginIn', window.localStorage.getItem('token')); // 得到token时需要存在本地
  }
 

猜你喜欢

转载自blog.csdn.net/qq_40963664/article/details/83270347
今日推荐