先看看main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router/index'
import dynamicRouter from './router/dynamic-router'
import store from './store/index'
import authorize from './utils/base/authorize'
import network from './utils/base/network'
import config from './utils/config/config'
import api from './utils/config/api'
import toastRegistry from './components/plugins/toast/index'
import confirmRegistry from './components/plugins/confirm/index'


//全局js引用
Vue.prototype.$api=api
Vue.prototype.$network=network


// 全局插件引用
Vue.use(toastRegistry)
Vue.use(confirmRegistry)


//导航守卫
router.beforeEach(async (to,from,next)=>{

  if(to.meta.requiresAuth===false){
    //不需要登录的直接放行
    next()
  }else if(!authorize.checkLogin()){
    //如果页面需要登录,且登录失效,进入登录页面
    next({
      path:config.login_path,
      query: { redirect: to.fullPath }
    })
  }else {
    //已经登录
    //是否已经拉取menu,权限等信息
    if(!store.state.menu_loaded){
      //如果页面还没有拉取menu
      await network.post(api.get_user_info,'',true).then((res)=>{
        console.log(res);
        
        store.commit('SET_USER_INFO',res)
        let dy_routers=dynamicRouter.generateRouteByPermision(dynamicRouter.routes,res.permission);
        router.addRoutes(dy_routers)

      })
      next({ ...to, replace: true })

    }else{
      next()
    }

  }

})

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

network.js封装axios 使用 qs.stringify()将对象 序列化成URL的形式,以&进行拼接 ,并且验证登录是否过期

import authorize from './authorize'
import api from '../config/api'
import config from '../config/config'
import axios from 'axios'
import Qs from 'qs'
import router from '../../router'


function toLogin(redirect={go: -1}) {
  router.push({
    path: config.login_path,
    query:redirect
  })
}

function toForbidden() {
  router.push({
    path: config.forbidden_path
  })
}
/*
* check_login,请求数据之前,是否需要检查登录状态,如果登录已过期,则需要重新登录,然后再请求数据
*/
function get(url,data,check_login=false) {
  if(check_login&&!authorize.checkLogin()){
    //如果需要登录,且登录已经过期,则先进行登录,然后再进行数据处理
    return new Promise((resolve,reject)=>{
      toLogin()
      reject("登录过期,请先登录")
    })
  }

  return request(url,data,'get')
}

function post(url,data,check_login=false) {
  if(check_login&&!authorize.checkLogin()){
    //如果需要登录,且登录已经过期,则先进行登录,然后再进行数据处理
   return new Promise((resolve,reject)=>{
     toLogin()
     reject("登录过期,请先登录")
   })
  }

  return request(url,data,'post')
}

function request(url,data,method='get') {
  let params= method=='get'?data:'';
  let post_data= method=='post'?data:'';

  return new Promise((resolve,reject)=>{
    axios.request({
      url: api.baseUrl+url,
      method:method,
      params:{
        ...params,
        access_token:authorize.getToken()
      },
      data:post_data,

      transformRequest: [function (data) {
        return Qs.stringify(data);//把数据转化为QueryString
      }],

      headers:{
        'Content-Type':'application/x-www-form-urlencoded'
      },
      onUploadProgress:'',
      onDownloadProgress:''
    }).then((res)=>{
      res=res.data
      if(res.code=='1'){
        resolve(res.data)
      }else if(res.code=='401'){
        toLogin()
        reject("登录过期,请先登录")
      }else if(res.code=='403'){
        toForbidden()
        reject("缺少权限")
      }else if(res.code=='99'){
        reject(res.msg)
      }else {
        reject("未知code")
      }

    }).catch((err)=>{
      reject(err)
    })
  })

}

export default {
  get,post,toLogin
}

api.js文件中定义接口配置



export default {
  //通用
  baseUrl:process.env.API_ROOT,
  login:'/adm/v1/user/login',
  logout:'/adm/v1/user/logout',
  get_user_info:'/adm/v1/user/get-info',
  clear_cache:'/adm/v1/cache/clear',
  roles_index:'/adm/v1/roles/index',
  roles_save:'/adm/v1/roles/save',
  roles_detail:'/adm/v1/roles/detail',
  user_index:'/adm/v1/user/index',
  user_save:'/adm/v1/user/save',
  user_detail:'/adm/v1/user/detail',
  user_reset_password:'/adm/v1/user/save-pwd',
  user_update_password:'/adm/v1/user/update-pwd',
  category_index:'/adm/v1/category/index',
  category_save:'/adm/v1/category/save',
  menu_index:'/adm/v1/menu/index',
  menu_save:'/adm/v1/menu/save',
  menu_children:'/adm/v1/menu/children',
  menu_rights:'/adm/v1/menu/rights',
  news_index:'/adm/v1/news/index',
  news_save:'/adm/v1/news/save',
  news_detail:'/adm/v1/news/detail',
  member_index:'/adm/v1/member/index',
  member_save:'/adm/v1/member/save',
  banner_index:'/adm/v1/banner/index',
  banner_save:'/adm/v1/banner/save',
  banner_detail:'/adm/v1/banner/detail',
  stats_member_count:'/adm/v1/stats/member',
  stats_member_graph:'/adm/v1/stats/member-graph',

  //上传
  upload_server:'/adm/v1/file/up',//通过服务器上传的接口地址
  upload_client:'https://upload.qiniup.com',//通过客户端直接上传到七牛云的接口地址

  //项目专有
  course_index:'/adm/v1/course/index',
  course_save:'/adm/v1/course/save',
  course_detail:'/adm/v1/course/detail',
  lesson_index:'/adm/v1/course/lesson-index',
  lesson_save:'/adm/v1/course/lesson-save',
  lesson_detail:'/adm/v1/course/lesson-detail',
  topic_index:'/adm/v1/course/topic-index',
  topic_save:'/adm/v1/course/topic-save',
  topic_detail:'/adm/v1/course/topic-detail',
  get_topic_news:'/adm/v1/course/get-topic-news',
  topic_news_save:'/adm/v1/course/topic-news-save',
  demo_index:'/adm/v1/course/demo-index',
  demo_save:'/adm/v1/course/demo-save',
  demo_detail:'/adm/v1/course/demo-detail',
}

我们已经在 main.js中引入了 api.js 和 network.js并且绑定要原型链上全局js引用

并且运用了vuex判断是否 是否已经拉取menu,权限等信息

最后用 router.addRoutes 添加动态路由


Lifelong learning lifelong benefit