当前位置: 首页 > 知识库问答 >
问题:

vue-router - vue2 router 执行 next() 为什么没有进页面?

小牛23354
2024-12-29

路由拦截部分代码如下:

export default (to, from, next,router) => {

  console.log('beforeEach-----------------------------begin-----------------------------to.path')
  console.log('to.path:'+to.path)

  // 如果路由为空,添加路由
  if(router.getRoutes().length===0) {
    router.addRoutes(store.getters['router/staticRoutes'])
  }

  // 白名单页面路由
  // let whiteList=["/login","/404","/home","/testo","/testt","/testt/tests",'/testo/testw','/']
  let whiteList=["/login","/404"]
  // token
  let token=localStorage.getItem('token')
  // 动态路由表
  let routes=store.state.router.menu

  // 没有token && 目标路由在白名单
  if(!token && whiteList.includes(to.path)){
    console.log('beforeEach--------------------------next_2')
    next()
  }

  // 没有token && 目标路由不在白名单
  if(!token && !whiteList.includes(to.path)){
    console.log('beforeEach--------------------------next_3')
    console.log(`next_path--------------------------/login?redirect=${to.path}`)
    next(`/login?redirect=${to.path}`)
  }

  // 有token && 目标路由是登录页
  if(token && to.path=='/login'){
    console.log('beforeEach--------------------------next_4')
    console.log(`next_path--------------------------path: '/home'`)
    next({ path: '/home' })
  }

  // 有token && 目标路由不是登录页 && 已经有路由表hasRoles
  if(token && to.path!='/login' && routes.length!==0){
    console.log('beforeEach--------------------------next_5')
    next()
  }

  // 有token && 目标路由不是登录页 && 没有路由表hasRoles
  if(token && to.path!='/login' && routes.length==0 ){

    store.dispatch('router/getRoutes').then(res=>{

      // 路由数据存到 store 里面了,添加一次路由然后跳转
      router.addRoutes(store.getters['router/staticRoutes'])
        console.log('beforeEach--------------------------next_6')
        console.log(`next_path--------------------------/login?redirect=${to.path}`)
        next(`/login?redirect=${to.path}`)
    })
  }

}

没登陆之前直接输入地址:
http://localhost:8081/
或者
http://localhost:8081
都会跳转到:
http://localhost:8081/login?redirect=%2F
页面也会正常显示:
image.png
或者在地址栏直接输入主页面地址:
http://localhost:8081/home
也会判断有没有登录然后重定向回登录页:
image.png
这里的 redirect 参数本意是要留到登陆页面后面登陆成功后就直接跳转到用户的目标页面用的,
但我直接输入登录页地址:
http://localhost:8081/login
next()也执行了,但是并没有进入登录页,也没有报错:
image.png
我的路由配置是写在 store 中,通过路由拦截动态添加的,具体如下:


import Layout from "@/layout/index.vue";
import {  getRoutesAPI } from "@/api/userApi";
const state = {
  // 静态路由
  staticMenu:[
    // 访问根路径切换回到home
    {
      path: '/',
      component: Layout,
      redirect: '/home',
    },

    // 登录页
    {
      path: '/login',
      component: () =>
        import('@/views/login/index'),
      hidden: true
    },

    //   找不到页面
    {
      path: '/404',
      component: () =>
        import('@/views/errorPage/404'),
      hidden: true
    },

    // 匹配不到的页面全部跳转到404
    {
      path: '*',
      redirect: '/404', // 将所有未匹配到的路由重定向到404路由
      hidden: true
    },

  ],
  
  menu:[],

}

const getters={
  staticRoutes(state){
    return state.staticMenu.map(item=>{
      if(item.path=='/'){
        item.children=state.menu
      }
      return item
    })
  },
}

const mutations = {
  SET_MENU: (state, menu) => {
    state.menu=routeFormat(menu)
  },
}

const actions = {
  // 获取动态路由
  getRoutes({ commit }){
    return getRoutesAPI().then((ref)=>{
      commit('SET_MENU',ref.data)
      return (ref)
    }).catch(e=>e)
  }
}

// 路由表格式化
function routeFormat(routeList){
  return routeList.map(item=>{
    let timeObj= JSON.parse(JSON.stringify(item))
    timeObj.component = () => import('@/views'+item.component)
    timeObj.meta=JSON.parse(item.meta)
    if(item.ChildList){
      timeObj.ChildList=routeFormat(item.ChildList)
    }
    return timeObj
  })
}

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}

但是我个人觉得这个应该和路由配置没有关系,因为之前是能进去的,和登录页面应该也没有关系,前面那一串 ?????是 登录页面中的

  beforeMount() {
    console.log("?????????????????")
  },

所以这个空白页应该也不是登录页组件里面的问题,但是又想不到还能是哪里的问题,接下来应该从哪里着手排查?
----------------------------------------ps 补充解释------------------------------------------

把路由守卫所有判断逻辑都删掉,简化成如下代码后依然是不能直接访问:

//路由创建脚本
import Vue from 'vue'
import Router from 'vue-router'
import beforeEachCallback from './beforeEach'

Vue.use(Router)

const createRouter = () => new Router({
  scrollBehavior: () => ({ y: 0 }),
  base:'/',
  mode:"history",
})
const router = createRouter()

router.beforeEach((to, from, next)=>{beforeEachCallback(to, from, next,router)})

export default router

//路由守卫回调
import store from '@/store'
export default (to, from, next,router) => {

  console.log('beforeEach-----------------------------begin-----------------------------to.path')
  console.log('to.path:'+to.path)

  // 如果路由为空,添加路由
  if(router.getRoutes().length===0) {
    router.addRoutes(store.getters['router/staticRoutes'])
  }

  next()

}

现在守卫已经直接放行了,依然进不去,所以应该不是路由守卫里的逻辑问题。

前面路由守卫贴出详细代码主要是为了说明虽然直接写 url 进不去,但是通过判断跳转后尽然还能跳转进去,所以路由配置应该也没问题吧。。。。

共有2个答案

许涵容
2024-12-29

建议使用debug排查,应该很快就会解决

image.png

或者使用vscode直接debug调试,内部的运行流程很快就整明白,vscode调试不清楚的可以 看下这篇文章 vscode调试

洪旻
2024-12-29

路由守卫逻辑问题,建议重构一下路由

// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import beforeEachCallback from './beforeEach'
import store from '@/store'

Vue.use(Router)

const createRouter = () => new Router({
  scrollBehavior: () => ({ y: 0 }),
  base:'/',
  mode:"history",
  routes: store.getters['router/staticRoutes'] // 创建的时候就加静态路由
})

const router = createRouter()

router.beforeEach((to, from, next) => {
  console.log('beforeEach-----------------------------begin-----------------------------to.path')
  console.log('to.path:'+to.path)

  // 白名单路由
  let whiteList=["/login","/404"]
  let token = localStorage.getItem('token')

  if (!token && whiteList.includes(to.path)) {
    return next()
  }

  if (!token && !whiteList.includes(to.path)) {
    return next(`/login?redirect=${to.path}`)
  }

  if (token && to.path === '/login') {
    return next('/home')
  }

  if (token && !store.state.router.menu.length) {
    store.dispatch('router/getRoutes').then(() => {
      // 加动态路由之后要加上 replace: true
      next({ ...to, replace: true })
    })
  } else {
    next()
  }
})

export default router

在登录页里加生命周期钩子测试一下看看:

export default {
  name: 'Login',
  created() {
    console.log('Login component created');
  },
  mounted() {
    console.log('Login component mounted');
  },
  beforeDestroy() {
    console.log('Login component beforeDestroy');
  }
}
 类似资料:
  • 本文向大家介绍vue-router怎么重定向页面?相关面试题,主要包含被问及vue-router怎么重定向页面?时的应答技巧和注意事项,需要的朋友参考一下 redirect中写一个路径就可以

  • 本文向大家介绍vue-router怎么配置404页面?相关面试题,主要包含被问及vue-router怎么配置404页面?时的应答技巧和注意事项,需要的朋友参考一下

  • 我使用surefire和failsafe分别执行单元测试和集成测试。所有测试都位于文件夹中。到目前为止,我有一个集成测试类,其测试方法(用@test注释)在所有单元测试运行时从不执行。这是我的pom的摘录。xml: 我使用maven目标来运行测试。

  • 我正在尝试将一个梅文Spring靴(2.3.12)应用程序从JUnit4转换为JUnit5。我已经阅读了很多关于如何做到这一点的不同帖子。 我能够在Eclipse中执行我的JUnit5测试。 我的问题是我无法让Maven Surefire执行我的JUnit5测试。我尝试了各种配置变体。当它到达Surefire步骤时,它只执行我以前的JUnit4测试,并且简单地忽略任何JUnit5测试。我已经验证了

  • 今天在写一个demo的时候 引入了一个编辑器 然后在router中没有注册demo页面 demo/index 下 components/editor/index 为什么页面没有注册的情况下 打包工具分析还是打包进去了? 占了800多kb 求老法师解惑 感谢 emmmmmm 为什么没人回答呢

  • 我有一个C++实验室,问题是:用户应该为X输入一个值(X是所持有的测试数)。如果x<15,程序不计算任何东西。如果X在16和30之间,程序应计算C=1.0/10.0*(24a);如果X>30,程序应计算C=0.15(24*a)。我的multiple if代码可以工作,但是当我输入X的值时,方程没有解出。有人知道吗??

  • 我正在尝试了解更多关于程序集的信息,以及编译器可以做什么和不能做什么优化。 我有一段测试代码,对此我有一些问题。 在此处查看其实际操作:https://godbolt.org/z/pRztTT,或检查下面的代码和程序集。 GCC 10.1 生产的 -O3 组件: GCC似乎产生了两个版本的循环:一个具有条件但没有条件,另一个没有任何条件。 我的问题: 是什么阻止了海湾合作委员会分裂出全部条件?它与