Skip to content

Vue Router

Vue Router 是 Vue.js 的官方路由管理器,它与 Vue.js 核心深度集成,使构建单页面应用变得更加简单。

什么是路由?

路由是指根据 URL 的变化来展示不同的页面内容。在单页面应用 (SPA) 中,路由可以实现页面的切换而不需要刷新整个页面。

Vue Router 安装

在 Vue3 项目中安装 Vue Router:

bash
npm install vue-router@4

基本配置

创建路由配置文件

javascript
// 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(),
  routes
})

export default router

在 main.js 中注册路由

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

const app = createApp(App)
app.use(router)
app.mount('#app')

路由跳转

vue
<template>
  <nav>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
  </nav>
  <router-view></router-view>
</template>

使用 useRouter 钩子

vue
<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

function goToHome() {
  router.push('/')
}

function goToAbout() {
  router.push('/about')
}
</script>

<template>
  <button @click="goToHome">首页</button>
  <button @click="goToAbout">关于</button>
  <router-view></router-view>
</template>

路由参数

动态路由

javascript
// router/index.js
const routes = [
  {
    path: '/user/:id',
    name: 'User',
    component: () => import('../views/User.vue')
  }
]

接收路由参数

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

const route = useRoute()
const userId = route.params.id
</script>

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

查询参数

javascript
// 跳转到带查询参数的路由
router.push({
  path: '/search',
  query: {
    keyword: 'Vue3',
    page: 1
  }
})

// 接收查询参数
const keyword = route.query.keyword
const page = route.query.page

嵌套路由

javascript
// router/index.js
const routes = [
  {
    path: '/user',
    component: User,
    children: [
      {
        path: 'profile',
        component: UserProfile
      },
      {
        path: 'settings',
        component: UserSettings
      }
    ]
  }
]
vue
<!-- User.vue -->
<template>
  <div>
    <h2>用户中心</h2>
    <nav>
      <router-link to="/user/profile">个人资料</router-link>
      <router-link to="/user/settings">设置</router-link>
    </nav>
    <router-view></router-view>
  </div>
</template>

重定向和别名

重定向

javascript
const routes = [
  {
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    component: Home
  }
]

别名

javascript
const routes = [
  {
    path: '/home',
    component: Home,
    alias: '/index'
  }
]

404 页面

javascript
const routes = [
  // 其他路由...
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: () => import('../views/NotFound.vue')
  }
]

路由守卫

全局前置守卫

javascript
router.beforeEach((to, from, next) => {
  // 检查用户是否登录
  const isLoggedIn = localStorage.getItem('token')
  
  // 如果访问需要登录的页面且未登录,重定向到登录页
  if (to.meta.requiresAuth && !isLoggedIn) {
    next('/login')
  } else {
    next()
  }
})

路由元信息

javascript
const routes = [
  {
    path: '/dashboard',
    component: Dashboard,
    meta: {
      requiresAuth: true
    }
  }
]

组件内守卫

vue
<script setup>
import { onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()

// 组件内的路由守卫
onMounted(() => {
  // 可以在这里进行路由相关的逻辑
})
</script>

实战示例

完整的路由配置

javascript
// router/index.js
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')
  },
  {
    path: '/user/:id',
    name: 'User',
    component: () => import('../views/User.vue'),
    children: [
      {
        path: 'profile',
        component: () => import('../views/UserProfile.vue')
      },
      {
        path: 'settings',
        component: () => import('../views/UserSettings.vue')
      }
    ]
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import('../views/Login.vue')
  },
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: () => import('../views/NotFound.vue')
  }
]

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

// 全局前置守卫
router.beforeEach((to, from, next) => {
  // 检查需要登录的路由
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  const isLoggedIn = localStorage.getItem('token')
  
  if (requiresAuth && !isLoggedIn) {
    next('/login')
  } else {
    next()
  }
})

export default router

导航组件

vue
<template>
  <div class="nav">
    <router-link to="/" class="nav-link">首页</router-link>
    <router-link to="/about" class="nav-link">关于</router-link>
    <router-link to="/user/1" class="nav-link">用户中心</router-link>
    <button @click="logout" v-if="isLoggedIn" class="nav-link">退出登录</button>
    <router-link to="/login" v-else class="nav-link">登录</router-link>
  </div>
  <div class="main">
    <router-view></router-view>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'

const router = useRouter()
const isLoggedIn = ref(false)

onMounted(() => {
  isLoggedIn.value = !!localStorage.getItem('token')
})

function logout() {
  localStorage.removeItem('token')
  isLoggedIn.value = false
  router.push('/login')
}
</script>

<style scoped>
.nav {
  display: flex;
  gap: 20px;
  padding: 20px;
  background-color: #f0f0f0;
}

.nav-link {
  text-decoration: none;
  color: #333;
  padding: 8px 16px;
  border-radius: 4px;
}

.nav-link:hover {
  background-color: #e0e0e0;
}

.main {
  padding: 20px;
}
</style>

通过本章的学习,我们掌握了 Vue Router 的基本使用方法,包括路由配置、路由跳转、路由参数、嵌套路由、重定向、404 页面和路由守卫等。这些知识是构建单页面应用的基础,将帮助我们创建更加复杂和功能完整的 Vue 应用。

© 2026 编程马·菜鸟教程 版权所有