发布时间:2023-05-23 文章分类:WEB开发, 电脑百科 投稿人:王小丽 字号: 默认 | | 超大 打印

vue- router里踩坑太多,全记录在这里,持续更新

1.父组件中要配置路由出口 RouterView

<template>
  <div class="main">
    <router-view></router-view>
  </div>
</template>

2.检查路由表配置

export default new Router({
  routes: [  // 1.这里不要写成route,注意是复数!
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
      path: '/hi',
      component: Hi,
      children: [  
      	// 2.子路由路径 不要加 /
        {path: '/hi2', component: Hi2}, // 错误写法
        {path: 'hi3', component: Hi3}// 正确写法
      ]
    }
  ]
})

component配置项

layout 这个路由跳转后重定向到 ‘/user/manage’,虽然这个路由被重定向,但是组件也要注册,否则它的子组件 userManage 无法挂载。

错误写法:

{
    path: '/user',
    name: 'user',
    redirect: '/user/manage', // 此路由跳转后重定向到 '/user/manage'
    children: [
      {
        path: '/user/manage',
        name: 'userManage',
        component: () => import('@/views/user-manage'),
      }
  }

正确写法:

{
    path: '/user',
    name: 'user',
    component: () => import('@/views/layout'),  // 虽然这个路由被重定向,但是不要忘记 注册组件
    redirect: '/user/manage', // 此路由跳转后重定向到 '/user/manage'
    children: [
      {
        path: '/user/manage',
        name: 'userManage',
        component: () => import('@/views/user-manage'),
      }
  }

3. 使用 transition组件后页面空白

确保路由组件中只有一个根节点

虽然 Vue3的 template 中可以使用多个根节点,但是<transition>中的组件渲染无法设置动画的非元素根节点,换句话,<transition>中的组件中只能有一个根节点。
多个根节点会导致 过渡无法生效,组件无法切换就出现了空白页。

<template>
	<div>A1</div>
	<div>A1</div>
</template>
<template>
<div>
    <div>A1</div>
    <div>A1</div>
 </div>
</template>

注意:注释标签也是节点,例如以下属于多个根节点

<template>
<!-- 注释 -->
<div>
    <div>A2</div>
     <div>A2</div>
</div>
</template>

component组件添加key值

于Vue机制的原因,为了性能会使用同一个元素。也就是说你切换时并不会更换掉整个元素,而是替换掉该元素中的内容的值,以此来切换,所以在这里需要添加key。

为了保证key的唯一性,可以使用route的path来作为key。

<router-view v-slot="{ Component,route  }">
    <transition name="fade" mode="out-in">
        <component :is="Component" :key="route.path"/>
    </transition>
</router-view>

添加动态路由后页面空白

使用 addRoutes 动态添加路由跳转后页面刷新空白

原因:(动态)异步路由添加,执行addRoutes是需要时间的,刚刚addRoutes()就执行next()立刻访问被添加的路由,然而此时addRoutes()没有执行结束,因而找不到刚刚被添加的路由导致白屏。

解决方法:使用 next({…to}),从新访问一次路由 (结束当前导航,执行新的导航,再次执行beforeEach回调,直到 {…to}路径找到为止,才执行next()

// 全局 前置守卫
router.beforeEach(async(to, from, next) => {
  document.title = getPageTitle(to.meta.title)
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
    } else {
      const hasGetUserInfo = store.getters.name
      if (hasGetUserInfo) {
        next()
      } else {
        try {
          await store.dispatch('user/getInfo')
          // next(path) 中断当前导航,执行新的导航
          // 如果 addRoutes 并未完成,路由守卫会一层一层的执行,直到 addRoutes 完成,找到对应的路由才会放行
          next({ ...to, replace: true }) // 正确写法
          // next() // 错误写法
        } catch (error) {
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    ...
})

其他

如果以上操作排查不出原因,可能是组件自身无法渲染,与路由切换无关,不要注册路由组件,直接开一个页面渲染该组件,再排查原因