Vue Router 路由指南

版本说明
本笔记同时涵盖 Vue 2 + vue-router 3 与 Vue 3 + vue-router 4 的核心用法,并在关键处注明版本差异。

  • Vue 3 用户:推荐使用 vue-router 4.x(与 Vue 3 配套)。
  • Vue 2 用户:请使用 vue-router 3.x,笔记中保留相关兼容提示。

Vue Router 简介

Vue Router 是 Vue.js 官方的路由管理器,与 Vue 核心深度集成,用于构建单页面应用(SPA)。它提供了丰富的功能:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式(IE9 自动降级)
  • 自定义滚动行为

官方文档Vue Router


安装 vue-router

Vue 3 项目(推荐使用最新稳定版)

npm install vue-router@4

Vue 2 项目(需指定 3.x 版本)

npm install vue-router@3.5.2

安装完成后,可在 node_modules 中确认是否存在 vue-router 文件夹。


快速上手示例

以下示例基于 Vue CLI 创建的项目(Vue 3),展示完整的路由配置流程。

清理项目

删除 src/assets 下的 logo 文件,删除 src/components 中的 HelloWorld 组件。

创建自定义组件

src/components 下新建两个组件:

Content.vue

<template>
  <h1>内容页面</h1>
</template>

<script>
export default {
  name: "Content"
}
</script>

<style scoped>
</style>

Main.vue(内容类似,名称改为 Main)

创建路由配置文件

新建 src/router/index.js

Vue 3 + vue-router 4 写法:

import { createRouter, createWebHistory } from 'vue-router'
import Content from '../components/Content.vue'
import Main from '../components/Main.vue'

// 路由配置数组
const routes = [
  {
    path: '/content',
    name: 'content',
    component: Content
  },
  {
    path: '/main',
    name: 'main',
    component: Main
  }
]

// 创建路由实例
const router = createRouter({
  history: createWebHistory(), // 使用 HTML5 历史模式
  routes
})

export default router

Vue 2 写法对比

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
export default new VueRouter({ routes })

在 main.js 中挂载路由

Vue 3 写法:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'  // 自动加载 index.js

const app = createApp(App)
app.use(router)                // 使用路由插件
app.mount('#app')

Vue 2 写法

new Vue({ router, render: h => h(App) }).$mount('#app')

在 App.vue 中使用路由链接和视图

<template>
  <div id="app">
    <h1>克峰</h1>
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容</router-link>
    <!-- 路由匹配的组件将渲染在此 -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
/* 全局样式 */
</style>

启动项目

npm run serve

路由嵌套(子路由)

在实际应用中,常有多层嵌套的组件组合。例如:/user/list 作为 /main 的子路由。

创建子组件

src/components/user/UserList.vue

<template>
  <h1>用户列表</h1>
</template>

<script>
export default {
  name: "UserList"
}
</script>

配置子路由

router/index.js 的父路由中添加 children 数组:

const routes = [
  {
    path: '/main',
    component: Main,
    children: [
      {
        path: 'user/list',        // 注意:不要加 /
        component: UserList
      }
    ]
  },
  // ... 其他路由
]

在父组件中添加 <router-view>

Main.vue 中需包含子路由出口:

<template>
  <div>
    <h1>主页面</h1>
    <router-view></router-view>   <!-- 子路由组件渲染在此 -->
  </div>
</template>

使用链接导航

<router-link to="/main/user/list">用户列表</router-link>

参数传递

布尔模式(将 route.params 作为组件的 props)

在路由配置中设置 props: true,即可自动将路由参数映射为组件 props。

路由配置:

{
  path: '/user/:id',
  component: UserDetail,
  props: true
}

组件中接收:

<script>
export default {
  props: ['id'],
  mounted() {
    console.log(this.id)  // 直接使用
  }
}
</script>

函数模式(更灵活)

{
  path: '/user/:id',
  component: UserDetail,
  props: (route) => ({ id: route.params.id, query: route.query })
}

重定向

使用 redirect 字段:

{
  path: '/home',
  redirect: '/main'         // 字符串路径
}
// 或使用命名路由
{
  path: '/home',
  redirect: { name: 'main' }
}

404 页面

配置一个通配符路由,匹配所有未定义路径。

  1. 创建 NotFound.vue 组件。
  2. 在路由配置末尾添加:
{
  path: '/:pathMatch(.*)*',   // Vue Router 4 语法
  name: 'NotFound',
  component: NotFound
}

Vue Router 3 语法path: '*'


路由模式

两种模式:

  • hash 模式:默认,URL 带 #(如 /#/main
  • history 模式:URL 美观(如 /main),需要服务器配置支持

createRouter 中指定:

const router = createRouter({
  history: createWebHistory(),      // history 模式
  // history: createWebHashHistory(), // hash 模式
  routes
})

导航守卫(路由钩子)

全局守卫

在路由配置文件中使用:

router.beforeEach((to, from, next) => {
  // 登录验证等逻辑
  if (to.meta.requiresAuth && !isLoggedIn) {
    next('/login')
  } else {
    next()
  }
})

路由独享守卫

{
  path: '/admin',
  component: Admin,
  beforeEnter: (to, from, next) => {
    // ...
  }
}

组件内守卫(选项式 API)

<script>
export default {
  beforeRouteEnter(to, from, next) {
    // 不能访问组件实例 `this`,但可通过 next(vm => {}) 访问
    next(vm => {
      vm.loadData()
    })
  },
  beforeRouteUpdate(to, from, next) {
    // 路由更新时调用(如参数变化)
    this.loadData()
    next()
  },
  beforeRouteLeave(to, from, next) {
    const answer = confirm('确定要离开吗?')
    if (answer) next()
    else next(false)
  }
}
</script>

组合式 API 中的守卫(Vue 3)

<script setup> 中使用:

<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'

onBeforeRouteLeave((to, from) => {
  const answer = window.confirm('确定离开?')
  if (!answer) return false
})

onBeforeRouteUpdate(async (to, from) => {
  // 响应路由参数变化
})
</script>

在路由守卫中发起异步请求

结合 Axios 示例(以组件内守卫为例):

  1. 安装 Axios

    npm install axios
    
  2. 全局挂载 Axios(Vue 3 方式)

    // main.js
    import axios from 'axios'
    const app = createApp(App)
    app.config.globalProperties.$axios = axios   // 全局属性
    
  3. 在组件中使用

    <script>
    export default {
      beforeRouteEnter(to, from, next) {
        next(vm => {
          vm.getData()   // 进入路由后调用方法
        })
      },
      methods: {
        getData() {
          this.$axios.get('/static/mock/data.json').then(res => {
            console.log(res.data)
          })
        }
      }
    }
    </script>
    

说明:在 Vue 3 中推荐使用组合式 API 直接导入 Axios,此处仅为演示兼容。


总结

通过本指南,你已经掌握了 Vue Router 的核心功能:

  • 基础路由配置与使用
  • 嵌套路由
  • 参数传递(props 模式)
  • 重定向与 404 处理
  • 路由模式选择
  • 导航守卫的多种用法
  • 结合异步请求

无论是维护 Vue 2 项目,还是开发全新的 Vue 3 应用,这些知识都是构建单页面应用的基石。更多高级用法请参考 官方文档

posted @ 2022-07-29 11:23  克峰同学  阅读(82)  评论(0)    收藏  举报