← 目录从零开始学vue3

路由管理(Vue Router 4)

2024/9/17

在 Vue 3 中,setup 函数结合 Vue Router 4 实现路由管理为项目带来更强的灵活性和清晰的逻辑结构。Vue Router 4 是 Vue 3 的官方路由库,支持各种现代化路由特性,如动态路由、路由守卫和路由懒加载。接下来,我们详细介绍如何在 Vue 3 中使用 Vue Router 4,包含动态路由、导航守卫的实现,并通过实例讲解实际场景的应用。

一、Vue Router 4 的基础使用

1. 安装 Vue Router 4

在 Vue 3 项目中使用 Vue Router 4 需要先安装依赖:

bash
npm install vue-router@4

2. 基本路由配置

首先,我们需要在项目中创建一个 router/index.js 文件,并定义路由规则:

js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';

const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/about', name: 'About', component: About },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

3. 在主文件中注册路由

在 main.js 文件中将路由器挂载到 Vue 应用中:

js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // 引入路由配置

const app = createApp(App);

app.use(router); // 注册路由
app.mount('#app');

4. 基础路由导航

在 Vue 组件中通过 router-link 进行导航:

vue
<template>
  <div>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-view></router-view> <!-- 显示匹配的路由组件 -->
  </div>
</template>

二、动态路由

动态路由允许我们定义具有可变部分的路径,常用于详情页等场景。

1. 动态路由定义

在路由配置中,可以使用 :param 语法定义动态路由:

js
const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/user/:id', name: 'User', component: User }, // 动态路由
];

例如,当访问 /user/123 时,:id 的值将为 123。

2. 动态参数获取

在动态路由匹配到的组件中,可以通过 useRoute 获取路由参数:

vue
<template>
  <div>
    <h1>用户 ID: {{ userId }}</h1>
  </div>
</template>

<script>
import { defineComponent } from 'vue';
import { useRoute } from 'vue-router';

export default defineComponent({
  setup() {
    const route = useRoute();
    const userId = route.params.id; // 获取动态参数

    return { userId };
  }
});
</script>

3. 动态路由的场景

动态路由常用于用户详情页面或文章详情页面。例如,电商网站的商品详情页 /product/:productId,通过 productId 动态获取对应商品的信息。

三、路由守卫

导航守卫用于控制路由切换前、切换后的逻辑。Vue Router 4 提供了全局、路由级别和组件内的导航守卫。

1. 全局守卫

全局守卫可以用于处理所有路由导航行为。常见的应用场景是权限控制或全局登录拦截。

  • beforeEach:在每次路由跳转前触发
  • afterEach:在路由跳转后触发
js
router.beforeEach((to, from, next) => {
  const isAuthenticated = !!localStorage.getItem('token'); // 简单判断是否登录
  if (to.name !== 'Login' && !isAuthenticated) {
    next({ name: 'Login' }); // 未登录时跳转到登录页
  } else {
    next(); // 否则继续跳转
  }
});

2. 路由守卫示例

js
const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/login', name: 'Login', component: Login },
  { 
    path: '/dashboard', 
    name: 'Dashboard', 
    component: Dashboard,
    meta: { requiresAuth: true } // 添加元信息用于权限验证
  }
];

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

// 导航守卫
router.beforeEach((to, from, next) => {
  const isAuthenticated = !!localStorage.getItem('token'); // 判断登录状态
  if (to.matched.some(record => record.meta.requiresAuth) && !isAuthenticated) {
    next('/login'); // 未登录则跳转到登录页
  } else {
    next(); // 放行
  }
});

3. 组件内守卫

组件内的导航守卫可以在组件生命周期中控制导航行为。主要有以下几个钩子:

  • beforeRouteEnter:在进入路由前调用
  • beforeRouteUpdate:在当前路由变化但复用组件时调用
  • beforeRouteLeave:在离开路由前调用
vue
<template>
  <div>这是用户详情页</div>
</template>

<script>
export default {
  beforeRouteEnter(to, from, next) {
    console.log('进入该路由之前');
    next();
  },
  beforeRouteLeave(to, from, next) {
    console.log('离开该路由之前');
    next();
  }
};
</script>

4. 路由守卫的场景

  • 登录拦截:如果用户未登录,则拦截用户的操作,重定向到登录页面。
  • 权限控制:根据用户的权限,决定是否允许用户访问某些路由,如后台管理页面。

四、路由懒加载

在大型项目中,懒加载路由有助于提高应用性能,尤其是首次加载的速度。Vue Router 4 支持使用动态导入来实现路由的懒加载。

1. 路由懒加载示例

通过 import() 函数动态导入组件实现懒加载:

js
const routes = [
  { 
    path: '/about', 
    name: 'About', 
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') 
  }
];

2. 懒加载的场景

路由懒加载通常用于大型 SPA(单页面应用)中,尤其是一些不常访问的页面,如用户设置页、帮助页等,避免加载过多的资源。

五、动态添加路由

Vue Router 4 提供了 addRoute 方法,可以动态添加路由,通常用于权限管理或模块化应用中。

1. 动态添加路由示例

js
const newRoute = {
  path: '/admin',
  name: 'Admin',
  component: () => import('../views/Admin.vue')
};

// 动态添加路由
router.addRoute(newRoute);

2. 场景

动态路由在基于权限的路由系统中非常常见。比如,当用户登录后,根据其角色动态加载不同的路由模块。

六、示例:完整的路由守卫与动态路由使用

js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import Login from '../views/Login.vue';
import User from '../views/User.vue';

const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/login', name: 'Login', component: Login },
  { path: '/user/:id', name: 'User', component: User, meta: { requiresAuth: true } }
];

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

// 全局导航守卫
router.beforeEach((to, from, next) => {
  const isAuthenticated = !!localStorage.getItem('token');
  if (to.matched.some(record => record.meta.requiresAuth) && !isAuthenticated) {
    next({ name: 'Login' });
  } else {
    next();
  }
});

export default router;

总结

  1. 基础路由:定义静态和动态路由,使用 router-link 进行导航。
  2. 动态路由:在路径中使用 :param 来定义动态路由。
  3. 路由守卫:通过全局守卫、路由级别守卫和组件内守卫来实现权限控制和路由拦截。
  4. 懒加载:通过动态导入实现路由懒加载,优化应用性能。

动态添加路由:通过 addRoute 方法实现基于权限的动态路由加载。