Vue 路由的学习

Vue 路由完全指南

Vue路由完全指南:从基础到实战,轻松掌握页面跳转核心

在Vue开发中,路由是实现单页面应用(SPA)页面切换的核心技术。无论是Vue2还是Vue3,路由都扮演着"导航指挥官"的角色,负责管理不同页面的渲染与切换逻辑。本文将基于Vue3+Vue Router 4,从路由基础、核心用法到实战技巧,系统掌握Vue路由的全部关键知识点。

一、路由基础:什么是Vue Router?

Vue Router是Vue官方提供的路由管理器,专门用于实现SPA应用的页面跳转。它的核心作用包括:

  • 管理URL与组件的映射关系

  • 实现无刷新页面切换(单页面特性)

  • 提供路由参数传递、嵌套路由等高级功能

  • 支持路由守卫、重定向等路由控制逻辑

Vue3对应的路由版本是Vue Router 4,相比Vue2的Router 3,它在API设计上更贴合Composition API,且支持TypeScript原生集成,性能也有显著提升。

二、环境搭建:Vue3中配置路由

1. 安装依赖

首先确保你的Vue3项目中安装了Vue Router 4:

npm install vue-router@4
# 或 yarn add vue-router@4

2. 基本配置步骤

步骤1:创建路由配置文件

src目录下新建router/index.ts,配置路由规则:

// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
// 导入路由组件(建议路由组件放在pages/views文件夹)
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'

// 创建路由实例
const router = createRouter({
  // 路由模式:history模式(URL无#)
  history: createWebHistory(),
  // 路由规则数组
  routes: [
    {
      path: '/home', // URL路径
      name: 'home', // 路由名称(可选,用于命名路由)
      component: Home // 对应的组件
    },
    {
      path: '/news',
      name: 'news',
      component: News
    },
    {
      path: '/about',
      name: 'about',
      component: About
    },
    // 重定向:默认跳转到home页面
    {
      path: '/',
      redirect: '/home'
    }
  ]
})

export default router

步骤2:在main.ts中注册路由

// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index' // 导入路由实例

const app = createApp(App)
app.use(router) // 注册路由
app.mount('#app')

步骤3:在根组件中使用路由出口

App.vue中添加路由导航和路由出口(用于渲染匹配的组件):

<!-- src/App.vue -->
<template>
  <div class="app">
    <h1>Vue路由实战</h1>
    <!-- 路由导航区:使用RouterLink组件 -->
    <nav class="nav">
      <RouterLink to="/home" active-class="active">首页</RouterLink>
      <RouterLink to="/news" active-class="active">新闻</RouterLink>
      <RouterLink to="/about" active-class="active">关于</RouterLink>
    </nav>
    <!-- 路由出口:匹配的组件将在这里渲染 -->
    <div class="content">
      <RouterView></RouterView>
    </div>
  </div>
</template>

<script setup lang="ts">
// 导入路由组件
import { RouterLink, RouterView } from 'vue-router'
</script>

<style scoped>
.nav {
  display: flex;
  gap: 20px;
  margin: 20px 0;
}
.active {
  color: #42b983;
  text-decoration: underline;
}
</style>

3. 路由模式说明

Vue Router提供两种路由模式,可通过createWebHistorycreateWebHashHistory选择:

模式 实现方式 优点 缺点
history模式 HTML5 History API URL无#,美观接近传统网站 需服务端配置,否则刷新404
hash模式 URL的hash值(#后内容) 兼容性好,无需服务端配置 URL带#,SEO优化较差

三、核心用法:路由导航与参数传递

1. 路由导航的两种方式

(1)声明式导航:RouterLink组件

RouterLink是Vue Router提供的导航组件,会自动渲染为<a>标签,且自带激活状态样式:

<!-- 字符串写法 -->
<RouterLink to="/home">首页</RouterLink>

<!-- 对象写法(推荐,支持传参) -->
<RouterLink :to="{ path: '/news', query: { id: 1 } }">新闻</RouterLink>

<!-- 命名路由写法(通过name跳转,更简洁) -->
<RouterLink :to="{ name: 'about' }">关于</RouterLink>

(2)编程式导航:useRouter钩子

在组件中通过代码控制路由跳转,需使用useRouter钩子获取路由实例:

<script setup lang="ts">
import { useRouter } from 'vue-router'

const router = useRouter()

// 跳转页面
const goToNews = () => {
  // 字符串跳转
  router.push('/news')
  
  // 对象跳转(带query参数)
  router.push({ path: '/news', query: { id: 1 } })
  
  // 命名路由跳转(带params参数)
  router.push({ name: 'news', params: { id: 1 } })
  
  // 替换当前历史记录(不会新增历史条目)
  router.replace('/about')
}
</script>

2. 路由参数传递

Vue Router支持两种参数传递方式:query参数和params参数

(1)query参数

  • 特点:参数会拼接在URL后(如/news?id=1&title=xxx),刷新页面不丢失

  • 传递方式:

<!-- 声明式 -->
<RouterLink :to="{ path: '/news/detail', query: { id: 1, title: 'Vue路由教程' } }">
  查看新闻
</RouterLink>

<!-- 编程式 -->
router.push({ path: '/news/detail', query: { id: 1, title: 'Vue路由教程' } })
  • 接收方式:使用useRoute钩子获取路由信息
<script setup lang="ts">
import { useRoute } from 'vue-router'

const route = useRoute()
console.log(route.query.id) // 1
console.log(route.query.title) // Vue路由教程
</script>

(2)params参数

  • 特点:参数不会显示在URL中,需在路由规则中占位,刷新页面会丢失

  • 配置路由规则(必须占位):

routes: [
  {
    path: '/news/detail/:id/:title', // 占位符:参数名
    name: 'newsDetail',
    component: NewsDetail
  }
]
  • 传递方式:
<!-- 声明式 -->
<RouterLink :to="{ name: 'newsDetail', params: { id: 1, title: 'Vue路由教程' } }">
  查看新闻
</RouterLink>

<!-- 编程式 -->
router.push({ name: 'newsDetail', params: { id: 1, title: 'Vue路由教程' } })
  • 接收方式:
<script setup lang="ts">
import { useRoute } from 'vue-router'

const route = useRoute()
console.log(route.params.id) // 1
console.log(route.params.title) // Vue路由教程
</script>

3. 路由props配置

为了让路由组件更优雅地接收参数,可以通过props配置将路由参数转为组件props:

// 路由规则配置
{
  path: '/news/detail/:id/:title',
  name: 'newsDetail',
  component: NewsDetail,
  // 方式1:布尔值(仅对params参数生效)
  props: true,
  
  // 方式2:函数写法(支持query/params参数)
  props: (route) => ({
    id: route.query.id,
    title: route.query.title
  })
}

组件中直接通过props接收:

<script setup lang="ts">
const props = defineProps<{
  id: string
  title: string
}>()

console.log(props.id)
console.log(props.title)
</script>

四、高级特性:嵌套路由与路由守卫

1. 嵌套路由

实现页面内的子页面切换(如新闻列表页包含新闻详情页),需使用children配置项:

步骤1:配置嵌套路由规则

routes: [
  {
    path: '/news',
    name: 'news',
    component: News,
    // 子路由配置
    children: [
      {
        path: 'detail/:id', // 子路由路径无需加/
        name: 'newsDetail',
        component: NewsDetail
      }
    ]
  }
]

步骤2:在父组件中添加子路由出口

<!-- News.vue(父组件) -->
<template>
  <div class="news">
    <div class="news-list">
      <RouterLink v-for="item in newsList" :key="item.id" :to="{ name: 'newsDetail', params: { id: item.id } }">
        {{ item.title }}
      </RouterLink>
    </div>
    <!-- 子路由出口:子组件将在这里渲染 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
  </div>
</template>

2. 路由守卫

路由守卫用于控制路由的访问权限、监听路由变化等,常用的有全局守卫、路由独享守卫和组件内守卫。

(1)全局守卫

router/index.ts中配置,对所有路由生效:

// 全局前置守卫:路由跳转前触发
router.beforeEach((to, from, next) => {
  // to:即将进入的路由
  // from:即将离开的路由
  // next:放行函数(Vue3中可直接返回true/false或路由对象)
  
  // 示例:判断是否登录,未登录跳转到登录页
  const isLogin = localStorage.getItem('token')
  if (to.path !== '/login' && !isLogin) {
    return { name: 'login' } // 未登录,跳转到登录页
  }
  return true // 已登录,放行
})

// 全局后置守卫:路由跳转后触发(常用于页面标题设置)
router.afterEach((to, from) => {
  document.title = to.meta.title || 'Vue路由实战'
})

(2)组件内守卫

在组件中使用,控制当前组件的路由访问:

<script setup lang="ts">
import { onBeforeRouteEnter, onBeforeRouteLeave } from 'vue-router'

// 进入组件前触发
onBeforeRouteEnter((to, from, next) => {
  // 此时组件尚未创建,无法访问this
  console.log('进入组件前')
  next()
})

// 离开组件时触发
onBeforeRouteLeave((to, from, next) => {
  // 常用于提示用户保存数据
  const confirmLeave = window.confirm('是否确定离开?未保存的数据将丢失')
  if (confirmLeave) {
    next()
  } else {
    next(false) // 取消跳转
  }
})
</script>

五、实战技巧与注意事项

1. 路由组件与普通组件的区别

  • 路由组件:通常放在pages/views文件夹,通过路由跳转渲染,会被路由自动挂载/卸载

  • 普通组件:通常放在components文件夹,通过组件标签直接使用,需手动控制显示隐藏

2. 路由懒加载

为优化首屏加载速度,可使用路由懒加载(按需加载组件):

// 普通导入(首屏加载时全部加载)
import Home from '@/pages/Home.vue'

// 懒加载(访问时才加载)
const Home = () => import('@/pages/Home.vue')

// 路由配置
routes: [
  {
    path: '/home',
    component: Home
  }
]

3. 常见问题解决

(1)history模式刷新404

解决方案:服务端配置 fallback 到 index.html

  • Nginx配置:
location / {
  try_files $uri $uri/ /index.html;
}
  • Vercel配置(vercel.json):
{
  "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}

(2)路由参数变化不触发组件更新

当路由参数变化但组件未重新创建时(如/news/detail/1跳转到/news/detail/2),组件不会重新渲染。解决方案:

<script setup lang="ts">
import { useRoute, watch } from 'vue-router'

const route = useRoute()

// 监听路由参数变化
watch(
  () => route.params.id,
  (newId) => {
    // 执行参数变化后的逻辑(如重新请求数据)
    fetchData(newId)
  }
)
</script>

六、总结

Vue Router是Vue生态中不可或缺的核心插件,本文从基础配置、导航方式、参数传递到高级特性,全面覆盖了Vue3路由的关键知识点。掌握路由的核心在于理解"URL与组件的映射关系",并灵活运用各种API满足不同场景需求。

在实际开发中,建议结合项目特点选择合适的路由模式,合理使用路由守卫控制权限,通过懒加载优化性能。随着学习的深入,会继续探索动态路由、路由元信息等更高级的用法,让路由管理更加灵活高效。

posted @ 2025-11-21 19:40  Jade_Z  阅读(14)  评论(0)    收藏  举报