Vue的导航 -vue-router

233 阅读3分钟

Vue Router 是官方提供的路由管理库,它允许开发者在单页面应用(Single Page Application, SPA)中实现不同视图之间的平滑切换。本篇文章将详细介绍 Vue Router 的核心概念,并通过一系列的代码示例来帮助你更好地理解和掌握其用法。

一、安装和基本配置

首先,在使用 Vue Router 之前,我们需要将其安装到项目中。如果你使用的是 Vue CLI 创建的应用程序,可以通过以下命令快速安装:


npm install vue-router@next --save

接下来,在项目的入口文件 main.js 中引入并创建一个路由器实例:


// main.js
import { createApp } from 'vue';
import App from './App.vue';
import { createRouter, createWebHistory } from 'vue-router';

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

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

createApp(App).use(router).mount('#app');

这段代码定义了两个简单的路由:一个是首页,另一个是关于页面。我们还启用了历史模式,这使得URL看起来更加干净友好。

二、路由组件与导航

为了展示路由如何工作,我们需要创建对应的组件。这里以 Home.vueAbout.vue 为例:


<!-- Home.vue -->
<template>
  <div>
    <h1>欢迎来到首页</h1>
  </div>
</template>

<script>
export default {
  name: "Home",
};
</script>
html
深色版本
<!-- About.vue -->
<template>
  <div>
    <h1>关于我们</h1>
  </div>
</template>

<script>
export default {
  name: "About",
};
</script>

然后,在主应用组件 App.vue 中添加 <router-view> 标签,它是路由匹配到的组件渲染的地方:


<!-- App.vue -->
<template>
  <div id="app">
    <nav>
      <router-link to="/">首页</router-link> |
      <router-link to="/about">关于</router-link>
    </nav>
    <router-view></router-view>
  </div>
</template>

现在,当你访问根路径 / 或者 /about 时,相应的组件就会被渲染出来。

三、编程式导航与守卫

除了使用 <router-link> 进行声明式的导航外,Vue Router 还提供了编程式的方法如 router.push() 来动态改变当前的路由。此外,还有导航守卫可以用来控制页面跳转前后的逻辑,例如验证用户是否登录等。


// 在组件内部调用
this.$router.push({ name: 'About' });

// 定义全局前置守卫
router.beforeEach((to, from, next) => {
  console.log('Navigating from', from.path, 'to', to.path);
  next(); // 确保调用 next() 以继续导航
});

四、传递参数与嵌套路由

有时候我们需要根据URL中的参数来决定显示的内容,这时候就可以利用动态路由匹配。比如,要为每个用户创建独立的资料页,可以这样做:


const routes = [
  {
    path: '/user/:id',
    name: 'UserProfile',
    component: UserProfile,
    props: true // 将 URL 参数作为 props 传递给组件
  }
];

对于更复杂的应用场景,可能需要设置嵌套路由,即在一个页面内包含多个子页面。下面是一个例子:


const routes = [
  {
    path: '/users',
    component: UsersLayout,
    children: [
      { path: '', component: UsersList }, // 默认子路由
      { path: ':id', component: UserDetails }
    ]
  }
];

五、模块化路由配置

随着应用规模的增长,所有的路由规则都放在一个地方可能会变得难以管理。因此,推荐将路由拆分为多个模块,按照功能或业务领域进行组织。例如:


// routes/users.js
export default [
  {
    path: '/users',
    name: 'Users',
    component: Users,
    children: [
      { path: '', component: UsersList },
      { path: ':id', name: 'UserDetails', component: UserDetails, props: true }
    ]
  }
];

// routes/posts.js
export default [
  {
    path: '/posts',
    name: 'Posts',
    component: Posts,
    children: [
      { path: '', component: PostsList },
      { path: ':id', name: 'PostDetails', component: PostDetails, props: true }
    ]
  }
];

// main.js
import usersRoutes from './routes/users';
import postsRoutes from './routes/posts';

const routes = [...usersRoutes, ...postsRoutes];

这种方法不仅提高了代码的可读性和可维护性,而且也便于团队协作开发。

六、状态管理集成

当涉及到全局状态时,通常会结合 Vuex 或 Pinia 使用。假设我们要确保每次进入某个页面时都从服务器获取最新的数据,可以在路由守卫中触发相应的动作:

import store from './store';

router.beforeEach(async (to, from, next) => {
  if (to.name === 'PostDetails') {
    await store.dispatch('fetchPost', to.params.id);
  }
  next();
});