MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Vue Router 404页面与重定向功能的实现方式

2023-10-103.7k 阅读

Vue Router 404 页面的实现方式

一、基础概念

在前端应用中,404 页面(也称为“页面未找到”页面)是当用户试图访问不存在的路由时显示的页面。Vue Router 是 Vue.js 官方的路由管理器,它使得在 Vue 应用中实现单页面应用(SPA)的路由功能变得简单。通过合理配置 Vue Router,可以优雅地实现 404 页面。

二、使用通配符路由实现 404 页面

  1. 原理 在 Vue Router 中,可以使用通配符 * 来匹配所有未定义的路由。当用户访问的路由在路由表中没有找到对应的匹配项时,这个通配符路由就会生效,从而展示 404 页面。
  2. 代码示例 首先,创建一个 404 组件 NotFound.vue
    <template>
      <div>
        <h1>404 - Page Not Found</h1>
        <p>The page you are looking for does not exist.</p>
      </div>
    </template>
    
    <script>
    export default {
      name: 'NotFound'
    };
    </script>
    
    <style scoped>
    h1 {
      color: red;
    }
    </style>
    
    然后,在 router/index.js 中配置路由:
    import { createRouter, createWebHistory } from 'vue-router';
    import NotFound from '@/components/NotFound.vue';
    
    const routes = [
      // 其他正常路由配置
      {
        path: '/home',
        name: 'Home',
        component: () => import('@/views/Home.vue')
      },
      // 404 通配符路由
      {
        path: '/:catchAll(.*)',
        name: 'NotFound',
        component: NotFound
      }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
    在上述代码中,/:catchAll(.*) 是一个动态路由,其中 catchAll 是参数名,(.*) 表示匹配任意路径。当用户访问的路径在路由表中找不到匹配项时,就会渲染 NotFound 组件,显示 404 页面。

三、嵌套路由中的 404 页面处理

  1. 嵌套路由结构 假设应用有一个嵌套路由结构,例如一个用户管理模块,有用户列表页面和用户详情页面,且在这个模块下也可能出现 404 情况。
    const routes = [
      {
        path: '/users',
        name: 'Users',
        component: () => import('@/views/Users.vue'),
        children: [
          {
            path: '',
            name: 'UserList',
            component: () => import('@/views/UserList.vue')
          },
          {
            path: ':id',
            name: 'UserDetail',
            component: () => import('@/views/UserDetail.vue')
          }
        ]
      }
    ];
    
  2. 在嵌套路由中实现 404 要在嵌套路由中处理 404 页面,可以在父路由的 children 数组中添加一个通配符路由。
    const routes = [
      {
        path: '/users',
        name: 'Users',
        component: () => import('@/views/Users.vue'),
        children: [
          {
            path: '',
            name: 'UserList',
            component: () => import('@/views/UserList.vue')
          },
          {
            path: ':id',
            name: 'UserDetail',
            component: () => import('@/views/UserDetail.vue')
          },
          {
            path: '/users/:catchAll(.*)',
            name: 'UsersNotFound',
            component: () => import('@/components/UsersNotFound.vue')
          }
        ]
      }
    ];
    
    这里的 UsersNotFound.vue 组件可以是专门为用户模块定制的 404 页面。当用户在 /users 路径下访问不存在的子路由时,就会显示 UsersNotFound 组件。

四、404 页面的过渡效果

  1. 过渡效果原理 Vue 提供了过渡效果的功能,可以为 404 页面的显示和隐藏添加动画效果,提升用户体验。通过 transition 组件,可以定义入场和出场动画。
  2. 代码示例 首先,在 NotFound.vue 中添加 transition 组件:
    <template>
      <transition name="fade">
        <div>
          <h1>404 - Page Not Found</h1>
          <p>The page you are looking for does not exist.</p>
        </div>
      </transition>
    </template>
    
    <script>
    export default {
      name: 'NotFound'
    };
    </script>
    
    <style scoped>
    /* 定义 fade 过渡效果 */
    

.fade-enter-active, .fade-leave-active { transition: opacity 0.5s; } .fade-enter, .fade-leave-to { opacity: 0; }

在上述代码中,`transition` 组件的 `name` 属性设置为 `fade`,通过 CSS 定义了 `fade` 过渡效果的入场和出场动画,即透明度在 0.5 秒内渐变。

## Vue Router 重定向功能的实现方式

### 一、重定向基础概念
重定向是指当用户访问某个路由时,自动将其导航到另一个路由。在 Vue Router 中,重定向功能可以用于多种场景,例如处理旧版本路由变更、优化用户访问路径等。

### 二、简单重定向配置
1. **原理**
在路由配置中,可以使用 `redirect` 字段来指定重定向的目标路由。
2. **代码示例**
在 `router/index.js` 中配置重定向:
```javascript
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  {
    path: '/old - page',
    redirect: '/new - page'
  },
  {
    path: '/new - page',
    name: 'NewPage',
    component: () => import('@/views/NewPage.vue')
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

在上述代码中,当用户访问 /old - page 时,会自动重定向到 /new - page,然后渲染 NewPage 组件。

三、基于命名路由的重定向

  1. 原理 除了直接指定路径,还可以通过命名路由进行重定向。这样做的好处是当路由路径发生变化时,只需要修改命名路由对应的路径,而不需要在每个重定向处修改路径。
  2. 代码示例
    import { createRouter, createWebHistory } from 'vue-router';
    
    const routes = [
      {
        path: '/old - page',
        redirect: { name: 'NewPage' }
      },
      {
        path: '/new - page',
        name: 'NewPage',
        component: () => import('@/views/NewPage.vue')
      }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
    这里通过 redirect: { name: 'NewPage' }/old - page 重定向到名为 NewPage 的路由。

四、动态重定向

  1. 原理 动态重定向允许根据某些条件来决定重定向的目标。可以通过函数来实现动态重定向,该函数接收路由的参数等信息,根据逻辑返回重定向的目标。
  2. 代码示例
    import { createRouter, createWebHistory } from 'vue-router';
    
    const routes = [
      {
        path: '/user/:type',
        redirect: to => {
          if (to.params.type === 'admin') {
            return '/admin - dashboard';
          } else {
            return '/user - dashboard';
          }
        }
      },
      {
        path: '/admin - dashboard',
        name: 'AdminDashboard',
        component: () => import('@/views/AdminDashboard.vue')
      },
      {
        path: '/user - dashboard',
        name: 'UserDashboard',
        component: () => import('@/views/UserDashboard.vue')
      }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
    在上述代码中,当用户访问 /user/:type 时,根据 type 参数的值来决定重定向到不同的路由。如果 typeadmin,则重定向到 /admin - dashboard,否则重定向到 /user - dashboard

五、重定向与 404 页面的结合

  1. 场景分析 在某些情况下,可能需要先进行重定向,然后如果重定向后的路由也不存在,再显示 404 页面。例如,应用有一些旧的 API 风格的路由,先重定向到新的路由风格,如果新路由风格也不存在,则显示 404。
  2. 代码示例 首先,配置重定向和 404 路由:
    import { createRouter, createWebHistory } from 'vue-router';
    import NotFound from '@/components/NotFound.vue';
    
    const routes = [
      {
        path: '/old - api - style/:id',
        redirect: to => `/new - api - style/${to.params.id}`
      },
      {
        path: '/new - api - style/:id',
        name: 'NewApiStyle',
        component: () => import('@/views/NewApiStyle.vue')
      },
      {
        path: '/:catchAll(.*)',
        name: 'NotFound',
        component: NotFound
      }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
    当用户访问 /old - api - style/:id 时,会先重定向到 /new - api - style/:id。如果 /new - api - style/:id 不存在,就会触发 404 通配符路由,显示 404 页面。

六、重定向的导航守卫应用

  1. 导航守卫与重定向 导航守卫可以在路由导航过程中进行拦截和处理。可以利用导航守卫来实现更加复杂的重定向逻辑,例如根据用户的登录状态进行重定向。
  2. 代码示例router/index.js 中添加导航守卫:
    import { createRouter, createWebHistory } from 'vue-router';
    import Home from '@/views/Home.vue';
    import Login from '@/views/Login.vue';
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/login',
        name: 'Login',
        component: Login
      }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    router.beforeEach((to, from, next) => {
      const isLoggedIn = localStorage.getItem('token');
      if (to.name!== 'Login' &&!isLoggedIn) {
        next({ name: 'Login' });
      } else {
        next();
      }
    });
    
    export default router;
    
    在上述代码中,beforeEach 导航守卫会在每次路由导航前检查用户是否登录(通过检查 localStorage 中的 token)。如果用户未登录且访问的不是登录页面,则重定向到登录页面。

七、重定向的性能考虑

  1. 重定向次数影响 过多的重定向会增加用户等待时间,因为每次重定向都需要重新加载页面(即使是单页面应用,也涉及到路由切换的过程)。例如,如果有 A -> B -> C -> D 这样的多次重定向链,会导致用户体验变差。因此,在设计重定向逻辑时,应尽量减少重定向的次数,确保路径优化。
  2. 预加载与重定向 在一些情况下,可以结合预加载技术来优化重定向的性能。例如,在用户触发可能导致重定向的操作前,提前预加载重定向目标页面的资源。在 Vue 中,可以使用 router - lazy - load 配合一些预加载插件来实现。假设应用有一个从 /old - page 重定向到 /new - page 的功能,并且 new - page 组件较大。可以在用户访问 /old - page 时,通过 router - lazy - load 的一些配置,提前请求 new - page 组件的代码,这样当重定向发生时,能够更快地渲染页面。
    const routes = [
      {
        path: '/old - page',
        redirect: '/new - page'
      },
      {
        path: '/new - page',
        name: 'NewPage',
        component: () => import(/* webpackPrefetch: true */ '@/views/NewPage.vue')
      }
    ];
    
    这里通过 webpackPrefetch: true 配置,告诉 webpack 在适当的时候提前预加载 NewPage.vue 的代码,提升重定向后的加载性能。

八、重定向在多语言应用中的应用

  1. 多语言路由与重定向 在多语言应用中,不同语言的路由可能存在差异,重定向可以用于处理不同语言版本之间的路由转换。例如,英文版本的路由是 /en/about,中文版本的路由是 /zh/about。当用户在英文版本下访问一个不存在的页面 /en/not - found,可以重定向到中文版本对应的可能存在的页面 /zh/not - found,或者统一重定向到中文版本的 404 页面。
  2. 代码示例 假设应用通过一个 lang 参数来表示语言版本,在路由配置中可以这样实现:
    import { createRouter, createWebHistory } from 'vue-router';
    import NotFound from '@/components/NotFound.vue';
    
    const routes = [
      {
        path: '/:lang/about',
        name: 'About',
        component: () => import('@/views/About.vue')
      },
      {
        path: '/:lang/:catchAll(.*)',
        redirect: to => {
          const newLang = to.params.lang === 'en'? 'zh' : 'en';
          return `/${newLang}/${to.params.catchAll}`;
        }
      },
      {
        path: '/:catchAll(.*)',
        name: 'NotFound',
        component: NotFound
      }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
    在上述代码中,当用户访问某个语言版本下不存在的路由时,会尝试重定向到另一个语言版本的相同路径。如果最终都找不到匹配的路由,则显示 404 页面。

九、重定向的 SEO 考虑

  1. SEO 与重定向 重定向对 SEO 有一定影响。搜索引擎在抓取页面时,会关注重定向的目标。如果重定向设置不当,可能会导致搜索引擎抓取到错误的页面或者增加抓取时间。例如,使用 301 永久重定向时,搜索引擎会认为原页面已永久移动到新页面,会更新索引。而 302 临时重定向则表示原页面临时移动到新页面。在 Vue Router 实现的前端重定向中,虽然主要影响的是用户端体验,但如果与后端重定向配合不当,也可能影响 SEO。
  2. 正确配置重定向以利于 SEO 假设应用有一个旧的页面 /old - content 重定向到新页面 /new - content。在后端服务器配置(如使用 Nginx)时,应确保使用正确的重定向类型。如果 /old - content 的内容已经完全迁移到 /new - content,应使用 301 重定向:
    server {
      location /old - content {
        return 301 /new - content;
      }
    }
    
    在前端 Vue Router 中,可以继续保留重定向配置,确保用户在客户端访问时也能正确导航:
    const routes = [
      {
        path: '/old - content',
        redirect: '/new - content'
      },
      {
        path: '/new - content',
        name: 'NewContent',
        component: () => import('@/views/NewContent.vue')
      }
    ];
    
    这样可以保证搜索引擎和用户都能正确访问到新的内容页面,提升 SEO 效果。

十、重定向在微前端架构中的应用

  1. 微前端架构与重定向 在微前端架构中,不同的子应用可能有自己独立的路由系统。重定向可以用于在子应用之间进行导航切换。例如,主应用有一个菜单,点击某个菜单项可能重定向到一个子应用的特定页面。
  2. 代码示例 假设主应用使用 Vue Router 管理路由,子应用也有自己的 Vue Router。在主应用的 router/index.js 中配置重定向到子应用的路由:
    import { createRouter, createWebHistory } from 'vue-router';
    
    const routes = [
      {
        path: '/sub - app - page',
        redirect: () => {
          // 假设子应用挂载在 /sub - app 路径下
          return '/sub - app/specific - page';
        }
      }
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
    在子应用的 router/index.js 中,要确保 /sub - app/specific - page 路由配置正确:
    import { createRouter, createWebHistory } from 'vue-router';
    
    const routes = [
      {
        path: '/specific - page',
        name: 'SpecificPage',
        component: () => import('@/views/SpecificPage.vue')
      }
    ];
    
    const router = createRouter({
      history: createWebHistory('/sub - app'),
      routes
    });
    
    export default router;
    
    这样,当用户在主应用访问 /sub - app - page 时,会重定向到子应用的 /sub - app/specific - page 页面。

十一、重定向的安全性考虑

  1. 防止重定向漏洞 在实现重定向功能时,要注意防止重定向漏洞。例如,恶意用户可能通过构造恶意的重定向 URL,将用户引导到钓鱼网站。在 Vue Router 中,要确保重定向的目标是应用内部的合法路由或者经过安全验证的外部链接。
  2. 安全验证实现 可以通过白名单机制来实现安全验证。假设应用允许重定向到某些特定的外部链接,在重定向逻辑中添加验证:
    const whiteList = ['https://example.com', 'https://another - valid - site.com'];
    const routes = [
      {
        path: '/redirect - to - external',
        redirect: to => {
          const target = to.query.target;
          if (whiteList.includes(target)) {
            return target;
          } else {
            // 重定向到内部错误页面
            return '/invalid - redirect';
          }
        }
      }
    ];
    
    在上述代码中,当用户访问 /redirect - to - external?target = https://some - url 时,会检查 target 是否在白名单中。如果在,则重定向到该链接;否则,重定向到内部的错误页面 /invalid - redirect,从而防止用户被重定向到恶意链接。