Vue Router 路由管理

一、路由基础概念

1.1 路由的本质

路由在前端开发中扮演着至关重要的角色,它的核心本质是URL与UI组件之间的映射关系管理。从传统的多页面应用到现代单页面应用,路由的演进体现了Web开发理念的重大转变。

传统路由 vs 前端路由:

  • 传统路由:每次URL变化都向服务器请求新页面,导致完整页面刷新

  • 前端路由:URL变化只在客户端处理,通过JavaScript动态更新页面内容

1.2 SPA架构

单页面应用(SPA)不是简单的"一个HTML文件",而是一种应用架构模式

TypeScript 复制代码
// SPA核心特征示例
interface SPATraits {
  singleEntry: boolean;        // 单一入口
  clientSideRendering: boolean; // 客户端渲染
  dynamicUpdates: boolean;     // 动态更新
  ajaxDataFetching: boolean;   // AJAX数据获取
}

SPA的优势

  • 用户体验:接近原生应用的流畅度,无刷新跳转

  • 开发效率:前后端分离,并行开发

  • 性能优化:资源按需加载,减少服务器压力

SPA的挑战与解决方案

  • SEO问题:通过SSR(服务端渲染)或预渲染解决

  • 首屏加载:代码分割、懒加载优化

  • 状态管理:Vuex/Pinia等状态管理库

二、Vue Router安装与配置

2.1 环境准备与最佳实践

bash 复制代码
# 推荐使用Vue CLI或Vite创建项目
npm create vue@latest my-project
cd my-project
npm install vue-router@4

2.2 路由配置的完整架构

TypeScript 复制代码
// src/router/index.ts - 完整配置示例
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';

// 定义路由元信息类型,增强类型安全
declare module 'vue-router' {
  interface RouteMeta {
    requiresAuth: boolean;
    title: string;
    breadcrumb?: string[];
  }
}

// 路由配置数组
const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'Home',
    component: () => import('@/views/Home.vue'),
    meta: {
      requiresAuth: false,
      title: '首页'
    }
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('@/views/About.vue'),
    meta: {
      requiresAuth: false,
      title: '关于我们'
    }
  }
];

// 创建路由实例
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes,
  // 滚动行为控制
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition;
    } else {
      return { top: 0 };
    }
  }
});

export default router;

2.3 路由注册与应用初始化

TypeScript 复制代码
// src/main.ts - 完整注册流程
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

const app = createApp(App);

// 注册路由
app.use(router);

// 全局路由错误处理
router.onError((error) => {
  console.error('路由错误:', error);
});

app.mount('#app');

三、路由模式对比

3.1 History模式

实现原理

  • 基于HTML5 History API(pushState, replaceState)

  • 需要服务器配置支持

示例:

TypeScript 复制代码
const router = createRouter({
 history: createWebHistory(), //history模式
/******/
 });

3.2 Hash模式适用场景

技术特点

  • 使用URL hash(#)管理路由

  • 兼容性极佳,支持IE9+

适用场景

  • 静态网站部署

  • 无服务器配置权限

  • 对SEO要求不高的内部系统

示例:

TypeScript 复制代码
const router = createRouter({
 history: createWebHashHistory(), //hash模式
/******/
 });

|---------|----------------------------|------------------------------------|
| | 优点 | 缺点 |
| History | URL 更加美观,不带有#,更接近传统的网站 URL | 后期项目上线,需要服务端配合处理路径问题,否则刷新会有 404 错误 |
| Hash | 兼容性更好,因为不需要服务器端处理路径 | URL 带有#不太美观,且在 SEO 优化方面相对较差 |

四、路由导航全面

4.1 声明式导航高级用法

TypeScript 复制代码
<!-- 第一种:to的字符串写法 -->
 <router-link active-class="active" to="/home">主页</router-link>
 <!-- 第二种:to的对象写法 -->
 <router-link active-class="active" :to="{ path: '/home' }">Home</router-link>
TypeScript 复制代码
<template>
  <nav class="main-navigation">
    <!-- 基础导航 -->
    <RouterLink 
      to="/home" 
      active-class="active-link"
      exact-active-class="exact-active-link"
      class="nav-item"
    >
      首页
    </RouterLink>
    
    <!-- 对象语法 -->
    <RouterLink
      :to="{
        name: 'userProfile',
        params: { userId: 123 },
        query: { tab: 'settings' }
      }"
      class="nav-item"
    >
      用户设置
    </RouterLink>
    
    <!-- 自定义渲染 -->
    <RouterLink
      to="/cart"
      v-slot="{ href, route, navigate, isActive, isExactActive }"
      custom
    >
      <a
        :href="href"
        @click="navigate"
        :class="{
          'nav-item': true,
          'active': isActive,
          'exact-active': isExactActive
        }"
      >
        购物车
        <span v-if="route.meta.cartCount" class="badge">
          {{ route.meta.cartCount }}
        </span>
      </a>
    </RouterLink>
  </nav>
</template>

4.2 编程式导航完整指南

命名路由

可以简化路由跳转及传参

给路由规则命名

TypeScript 复制代码
routes: [
 {
 name: "zhuye",
 path: "/home",
 component: Home,
 },]

跳转路由

TypeScript 复制代码
<!--简化前:需要写完整的路径(to的字符串写法) -->
 <router-link to="/news/detail">跳转</router-link>
 <!--简化后:直接通过名字跳转(to的对象写法配合name属性) -->
 <router-link :to="{ name: 'guanyu' }">跳转</router-link>
TypeScript 复制代码
// 组合式API写法
import { useRouter, useRoute } from 'vue-router';

export default {
  setup() {
    const router = useRouter();
    const route = useRoute();
    
    const navigationMethods = {
      // 基础导航
      goToHome() {
        router.push('/home');
      },
      
      // 命名路由导航
      goToUserProfile(userId: number) {
        router.push({
          name: 'userProfile',
          params: { userId }
        });
      },
      
      // 带查询参数
      goToSearch(keyword: string) {
        router.push({
          path: '/search',
          query: { q: keyword, page: 1 }
        });
      },
      
      // 替换当前路由(不添加历史记录)
      replaceCurrent() {
        router.replace('/new-path');
      },
      
      // 前进后退
      goForward() {
        router.go(1);
      },
      
      goBack() {
        router.back();
      },
      
      // 条件导航
      conditionalNavigate() {
        if (route.name !== 'target') {
          router.push('/target');
        }
      }
    };
    
    return {
      ...navigationMethods
    };
  }
};

五、路由传参

5.1 Query参数

适用场景

  • 可选参数

  • 筛选条件

  • 分页信息

  • 排序参数

TypeScript 复制代码
<!-- 跳转并携带query参数(to的字符串写法) -->
 <router-link to="/news/detail?a=1&b=2&content=欢迎你">
跳转
</router-link>
 <!-- 跳转并携带query参数(to的对象写法) -->
 <RouterLink
 :to="{
 //name:'xiang', //用name也可以跳转
path: '/news/detail',
 query: {
 id: news.id,
 title: news.title,
 content: news.content,
 },
 }"
 >
 {{news.title}}
 </RouterLink>

<!--接收参数-->
import { useRoute } from "vue-router";
 const route = useRoute();
 // 打印query参数
console.log(route.query);

5.2 Params参数

路由配置

TypeScript 复制代码
{
  path: '/user/:userId/profile/:tab?',
  name: 'userProfile',
  component: UserProfile,
  props: true
}

参数传递与接收

TypeScript 复制代码
<template>
  <!-- 传递params参数 -->
  <RouterLink
    :to="{
      name: 'userProfile',
      params: {
        userId: 123,
        tab: 'settings'
      }
    }"
  >
    用户设置
  </RouterLink>
</template>

<script setup lang="ts">
// 接收params参数
import { defineProps } from 'vue';

interface Props {
  userId: string;
  tab?: string;
}

const props = defineProps<Props>();
</script>

备注: 1. 传递 params 参数时,若使用 to 的对象写法,必须使用 name 配置项,不能用 path

  1. 传递 params 参数时,需要提前在规则中占位

①to字符串写法+query/params实现传参

to字符串写法+query传参:

传: router-link的 to="路由路径+?键名=键值&键名=键值"

接: 接收route()方法中的 query属性值

to字符串写法+params传参:

前提条件:在路由配置的path中添加 路由路径/:参数1/:参数2

传: router-link的 to="路由路径/参数1/参数2"

接: 接收route()方法中的 params属性值

②to对象型写法-

1 name+query/params实现传参:

to对象型写法name+query传参

传: router-link的 to="{name:路由name,query:{k:v}}"

接: 接收route()方法中的 query属性值

to对象型写法name+params传参:

前提条件:在路由配置的path中添加 路由路径/:参数1/:参数2

传: router-link的 to="{name:路由name,params:{k:v}}"

接: 接收route()方法中的 params属性值

-2 path+query/params实现传参:

to对象型写法path+query传参:

传: router-link的 to="{path:路由name,query:{k:v}}"

接: 接收route()方法中的 query属性值

to对象型写法path+params传参:不能传递参数

5.3 Props配置的三种模式

作用让路由组件更方便的收到参数(可以将路由参数作为 props 传给组件)

TypeScript 复制代码
// 路由配置
{
  path: '/article/:id',
  name: 'article',
  component: Article,
  
  // 模式1:布尔模式 - 将params转为props
  // props: true,
  
  // 模式2:对象模式 - 传递静态props
  // props: { theme: 'dark', showAuthor: true },
  
  // 模式3:函数模式 - 动态计算props
  props: (route) => ({
    id: Number(route.params.id),
    query: route.query,
    meta: route.meta
  })
}

5.4replace 属性

作用控制路由跳转时操作浏览器历史记录的模式

浏览器历史记录写入方式

push:追加历史记录(默认值)

replace:替换当前记录

示例

TypeScript 复制代码
<RouterLink replace .......>News</RouterLink>

5.5重定向

作用 将特定的路径,重新定向到已有路由

具体编码

TypeScript 复制代码
{

 path:'/',
 redirect:'/about'
 }

404页面

TypeScript 复制代码
{

 path: "/:pathMatch(.*)*",
 name: "NotFound",
 component: NotFound,
 },

使用通配符 /:pathMatch(.) 匹配所有未定义的路径 对应 NotFound 组件

相关推荐
橘子编程1 小时前
仓颉语言:华为新一代编程利器
java·c语言·开发语言·数据库·python·青少年编程
___波子 Pro Max.1 小时前
Python argparse 参数解析用法详解
python
风华浪浪1 小时前
python 基础之 jsonpatch 用于对 JSON 文档的局部更新操作
linux·python·json
FeiHuo565151 小时前
微信个人号API二次开发:如何提高开发效率和质量
java·开发语言·python·php
wsj__WSJ1 小时前
Python 项目管理工具 uv 详解
python·conda·virtualenv
曲幽1 小时前
Flask入门:轻松掌握API路由定义
python·flask·web·route
s***35301 小时前
Python中的简单爬虫
爬虫·python·信息可视化
money05341 小时前
pytorch自定义backend
人工智能·pytorch·python
程序媛徐师姐2 小时前
Python基于Django的新闻发布类别自动识别系统【附源码、文档说明】
python·django·新闻发布类别自动识别系统·新闻发布类别自动识别·python新闻类别自动识别·pytho新闻类别识别系统·新闻发布类别识别系统