Vue 3 路由 (Vue Router)

在 Vue 3 中,Vue Router 是官方的路由管理库,用于构建单页应用(SPA)。它让你能够在不同的视图之间导航,并管理 URL 和状态。Vue Router 与 Vue 3 完全集成,允许你在应用中定义路由,支持嵌套路由、动态路由、路由守卫等功能。

1. 安装 Vue Router

首先,你需要安装 Vue Router:

npm install vue-router@4

Vue 3 中使用的是 Vue Router 4.x 版本。

2. 创建路由

2.1. 设置路由

在 Vue 3 中,创建路由的方法有点不同。你需要先创建一个 router/index.js 文件,定义所有的路由配置。

// src/router/index.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;

2.2. 配置路由和 Vue 实例

然后,在 main.js 中创建 Vue 应用并挂载路由:

// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

const app = createApp(App);

app.use(router); // 使用 Vue Router
app.mount('#app');

3. 路由视图和链接

3.1. 使用 <router-view> 显示路由内容

App.vue 中,你可以使用 <router-view> 标签来显示当前路由对应的组件内容。

<template>
  <div id="app">
    <h1>Vue 3 Router Example</h1>
    <nav>
      <router-link to="/">Home</router-link> | 
      <router-link to="/about">About</router-link>
    </nav>
    <router-view></router-view> <!-- 显示路由组件 -->
  </div>
</template>

  • router-link 用来定义路由链接,点击时会改变 URL 并加载相应的组件。
  • router-view 是一个占位符,Vue Router 会在这里渲染匹配的组件。

3.2. 定义组件

你可以创建不同的组件来作为路由的目标组件。

例如,创建一个 Home.vueAbout.vue

<!-- src/views/Home.vue -->
<template>
  <div>
    <h2>Welcome to the Home Page!</h2>
  </div>
</template>

<!-- src/views/About.vue -->
<template>
  <div>
    <h2>Welcome to the About Page!</h2>
  </div>
</template>

4. 路由参数

4.1. 路由传参

Vue Router 允许你通过 URL 传递参数,例如在 URL 中传递 ID。

// src/router/index.js
import Post from '../views/Post.vue';

const routes = [
  {
    path: '/post/:id', // 使用 :id 来定义参数
    name: 'Post',
    component: Post
  }
];

然后,在目标组件 Post.vue 中,使用 this.$route.params.id 来访问传递的参数:

<!-- src/views/Post.vue -->
<template>
  <div>
    <h2>Post ID: {{ postId }}</h2>
  </div>
</template>

<script>
export default {
  computed: {
    postId() {
      return this.$route.params.id; // 获取路由参数
    }
  }
};
</script>

4.2. 动态路由匹配

动态路由可以根据传递的参数来匹配不同的内容,支持任意数量和类型的参数。

5. 路由嵌套

Vue Router 支持嵌套路由,即在一个路由组件中渲染另一个路由组件。这可以用来实现多级导航。

// src/router/index.js
import Nested from '../views/Nested.vue';

const routes = [
  {
    path: '/nested',
    component: Nested,
    children: [
      {
        path: 'child',
        component: () => import('../views/Child.vue')
      }
    ]
  }
];

Nested.vue 中使用 router-view 来显示嵌套的子路由:

<!-- src/views/Nested.vue -->
<template>
  <div>
    <h2>This is the Nested Route</h2>
    <router-view></router-view> <!-- 子路由会在这里渲染 -->
  </div>
</template>

6. 编程式导航

除了使用 <router-link> 标签进行导航外,你还可以使用 Vue Router 的编程式导航来改变路由。

this.$router.push('/about'); // 导航到 /about

或者,使用 router.push 来编程式地跳转到其他路由:

this.$router.push({ name: 'Post', params: { id: 123 } });

7. 路由守卫

路由守卫允许你在路由发生变化之前或之后进行一些操作,比如验证用户是否已登录。

7.1. 全局守卫

// src/router/index.js
const router = createRouter({
  history: createWebHistory(),
  routes
});

router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isLoggedIn()) {
    next({ name: 'Login' }); // 如果用户未登录,重定向到登录页面
  } else {
    next(); // 继续路由
  }
});

export default router;

7.2. 路由独享守卫

每个路由也可以单独定义守卫:

{
  path: '/profile',
  name: 'Profile',
  component: Profile,
  beforeEnter(to, from, next) {
    if (!isLoggedIn()) {
      next({ name: 'Login' }); // 如果未登录,跳转到登录页
    } else {
      next(); // 否则,进入目标路由
    }
  }
}

7.3. 组件内守卫

你还可以在组件内部使用 beforeRouteEnterbeforeRouteLeave 守卫。

export default {
  beforeRouteEnter(to, from, next) {
    // 在进入路由之前
    next();
  },
  beforeRouteLeave(to, from, next) {
    // 在离开路由之前
    next();
  }
};

8. 路由懒加载

为了提高应用的性能,Vue Router 支持路由懒加载。你可以使用动态 import() 来实现懒加载,从而按需加载路由组件。

const routes = [
  {
    path: '/about',
    component: () => import('../views/About.vue') // 懒加载 About 组件
  }
];

9. 路由元信息 (meta)

Vue Router 允许你在路由配置中定义元信息(meta),你可以在路由守卫中检查这些信息。

const routes = [
  {
    path: '/admin',
    component: Admin,
    meta: { requiresAuth: true }
  }
];

然后,在全局守卫中检查 meta 信息:

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isLoggedIn()) {
    next({ name: 'Login' });
  } else {
    next();
  }
});

总结

  • 安装和配置:安装 vue-router 并在 Vue 实例中配置路由。
  • 路由链接:使用 <router-link><router-view> 来进行页面导航和显示。
  • 路由参数:支持动态路由和传递参数。
  • 嵌套路由:支持嵌套视图和子路由。
  • 编程式导航:使用 this.$router.push() 来编程式地导航。
  • 路由守卫:通过全局、路由独享、组件内守卫进行权限管理和路由控制。
  • 懒加载和路由元信息:优化性能,按需加载路由组件,并通过 meta 配置路由元数据。

Vue Router 提供了强大的路由管理功能,适用于各种复杂的单页应用场景。