路由概述

@Route
部署路由环境 创建路由 使用路由 渲染路由
Deployment
单独安装路由依赖并引入,比较麻烦,不推荐
1. 安装路由 - 为项目添加安装依赖
npm i vue-router -S
2. 引入路由 - 在入口文件 main.js 中引入路由,作为中间件使用;这里引入后,路由将作为 全局组件,其它组件可以直接使用
//引入
import router from './router'

//使用 - 链式
app.use(router).mount('#app')
创建项目的时候指定使用路由,自动生成路由配置文件
CreateRouter
使用路由功能,需要 vue-router 的支持
推荐 创建项目 的时候指定使用路由,自动生成路由配置文件
也可以 单独安装路由依赖;需要单独配置并引入,比较麻烦,不推荐
使用 createRouter() 函数,根据 路由选项 RouterOptions 创建路由实例 Router
路由选项 RouterOptions
属性 说明
history createWebHistory:大多 WEB 应用使用的模式,SEO 优化好;需要正确配置服务器
createWebHashHistory:基于 hash;SEO 优化体现一般;无须额外配置服务器
routes 路由列表;详细配置属性使用见下表
linkActiveClass?
linkExactActiveClass?
路由匹配样式
严格路由匹配样式
? 表示可选属性;下同
路由模式 History
历史记录模式
Vue2 使用 mode 配置项,Vue3 使用 history 配置项
需要引入对应的包再使用
1. createWebHistory()
HTML5 模式,URL 不带 #;传统网站模式
需要服务器端配合处理路径,否则容易出现 404;后端运维基本技能
http://localhost:5173/
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    // 
})
2. createWebHashHistory()
hash 模式;推荐模式
URL 带 #,看起来不够美观
SEO 优化性能略微不足
兼容性更好,不需要服务器端配合处理路径;前后端开发比较省心
优秀作品提交,请使用哈希模式
http://localhost:5173/#/
import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
    history: createWebHashHistory(import.meta.env.BASE_URL),
    // 
})
路由设计 Routes - RouteRecordRaw
按照值对形式 name-value pair 配置路由,即把 URL 路径映射到组件;其中,路径 path 和组件 component 必填
所有的路由配置位于项目 src → router 文件夹中,通常是 index.js
更多路由配置特性,请访问 路由定义和分类
建议在系统默认的路由配置文件 router → index.js 中,根据项目需求,相应的增加并修改
routes/RouteRecordRaw
属性 说明
path 路由;必填
component 对应路由的组件;必填
name 命名路由:通过名字来指定路由;不能重复;更直观、灵活,简化路由使用,如动态路由
redirect 重定向路由:让指定的路由重新定位到另外一个路由
children 嵌套路由、子路由;嵌套路由通常需要使用重定向
props 是否启用路由参数;可以接收动态路由参数和查询路由参数
meta 路由元信息:用于路由组件的额外配置;无法在编程式路由中定义或覆盖
beforeEnter 路由独享的守卫
1. 路径 path
/ 代表根路由
1.1 普通路由 - 仅仅指定路径
{
  path: '/menu',
  component: () => import('@/views/MenuView.vue'),
}
1.2 查询路由 - 路由传参的方式之一;以值对 name-value pair 的形式,通过 ? 拼接在路由后面;多个值对以 & 分割
使用/访问时传递参数,如用户分享
https://localhost:5173/menu?user=glpla.github.io
1.3 动态路由 - 路由传参的方式之一;以路径的方式拼接路由
便于实现视图共享 - 将给定匹配模式的路由映射到同一个组件,如 /goods/1 和 /goods/2 这样的 URL 都会映射到同一个路由 /goods: 在同一个页面根据 id 显示不同的商品
使用通配符 : - wild card 定义对应当前路由的动态路由
可以定义一个或多个;? 表示该参数可选
{
  path: '/details/:id',
  component: () => import('@/views/DetailsView.vue'),
}
https://localhost:5173/details?id=1001
1.4 异常路由 Caveat - 处理路由目标异常的情况,如 404,页面丢失
404 路由:使用自定义的路径参数|正则表达式匹配其它任意路径;通常是最后一个路由配置项
{
  path: '/:pathMatch(.*)*',
  name: 'NotFound',
  component: () => import('../views/NotFound.vue')
}
也可以使用 内置函数 h 生成 html,避免额外创建组件
404 路由也可以针对某个特定的路由
如果针对根路由和特定路由的404处理都存在,特定路由应该在根路由之前,否则无法正常匹配
import {h} from 'vue'
{
  path: '/goods:pathMatch(.*)*',
  name: 'goods-not-found',
  component: h('p', {style: 'color: red'}, 'goods 404 Not Found')
}
2. 组件 component
路由对应的视图
2.1 默认导入 Normal import - 系统就绪时,所有组件都已经显示导入;引入组件时,可以省略后缀名 .vue
import TeamView from "@/views/AboutView.vue";
{ 
  path: '/about', 
  component: TeamView,
}
2.2 动态导入 - 需要的时候才导入;懒加载
{ 
  path: '/about', 
  component: () => import("@/views/AboutView.vue")
}
3. 命名路由 Name - 使用 name 属性指定路由名称
路由命名应唯一
引用更方便、简洁,特别是长路由或多级嵌套路由
可读性好:采用语义化的命名
可维护性强:路由变化时,只改路由,命名可以保留
{
  path: '/center/login',
  component: () => import("@/views/LoginView.vue")
  name: 'login'
}
4. 重定向路由 Redirect
将一个路径重定向到另一个路径,适用于 URL 标准化、旧路径迁移和默认路径设置
嵌套路由不需要指定 component,因为它会重定向到目标路由,由目标路由的配置指定
可以直接使用 path;也可以使用命名路由 name - 推荐
{
  path: '/',
  // redirect: '/home',
  redirect: { name: 'home' },
},
{
  path: '/home',
  name: 'home'
  component: () => import("@/views/HomeView.vue") 
}
5. 嵌套路由 Nested Routes - 使用 children 属性指定子路由
用于构建复杂的 SPA,特别是多层嵌套视图
每个子路由都有自己的视图组件
为了渲染子路由对应的视图组件,父路由对应的组件应提供 <router-view>
子路由的 path 可以省略父级路由,不用 /;/代表根路由/根路径
嵌套路由的样式,如果不是全局的作用,应该单独设计。具体实现请查看 路由样式
可以使用模块化开发设计路由信息,便于管理和复用;见后续例子
{
  path: "/menu",
  component: () => import("@/views/MenuView.vue"),
  name: "menu",
  children: [
    {
      path: "goods", // 省略父级路由
      component: () => import("@/components/Goods.vue"),
      name: "goods"
    },
    {
      path: "vip", // 省略父级路由
      component: () => import("@/components/Vip.vue"),
      name: "vip"
    },
    {
      path: "/menu/rank", // 可以使用完整路由;建议所有子路由配置保持一致
      component: () => import("@/components/Rank.vue"),
      name: "rank"
    },
    {
      path: "/menu/favorite",
      component: () => import("@/components/Favorite.vue"),
      name: "favorite"
    }
  ]
}
通常情况下,父路由匹配时,除了渲染本身视图外,还会渲染某个子路由的视图;如果不特别处理,仅仅当子路由也匹配时,才会渲染
方案1:子路由使用空路由
{
  path: "/menu",
  component: () => import("@/views/MenuView.vue"),
  name: "menu",
  children: [
    {
      path: "", //空路由
      component: () => import("@/components/Goods.vue"),
      name: "goods"
    },
    // ...
  ]
}
方案2:父路由重定向到子路由 - 建议
{
  path: '/menu',
  redirect: { name: "goods" }, // 使用命名路由
  // redirect: '/menu/goods',  // 或使用完整路由
  component: () => import('@/views/MenuView.vue'),
  name: "menu",
  children:[
    {
      path: 'goods',
      component: () => import('@/components/Goods.vue'),
      name: "goods"
    },
    // ...
  ]
}
开发中,路由设计原则应该保持一致
6. 路由元数据 meta - 指定元信息,方便路由引用,如 导航守卫 时,更新页面标题;显示主导航菜单
{
  path: "/mall",
  name: "mall",
  component: () => import("@/views/MallView.vue"),
  meta: { showNav: true, title: "瑞幸电商" },
},
7. 路由独享的守卫 beforeEnter - 当前路由切换时触发,用以控制访问
8. 路由传参 props - 按照组件传参的形式传递路由参数
路由样式 linkActiveClass
严格匹配路由样式 linkExactActiveClass
Summary & Homework
Summary
history
routes

. path

. component

. name

. redirect

. children

. meta

linkActiveClass
linkExactActiveClass
Homework
[] 路由的 Vue 的模块化开发html 的模块化开发
除了直接配置路由 routes 外,还可以采用模块化 - 先定义再导入
方案1:普通导出 - 导入和导出需要指定名字
路由文件 routes.js:需要指定类型和名字
export const routes = [
  {
    path: "/",
    name: "home",
    component: () => import("@/views/HomeView.vue"),
  },
  // ...
];
router → index.js:导入时,需解构化并指定名字
import { routes } from "../assets/routes";
方案2:默认导出
路由文件 routes.js:默认导出,不需要指定类型和名字
export default [
  {
    path: "/",
    name: "home",
    component: () => import("@/views/HomeView.vue"),
  },
  // ...
];
router → index.js:导入时必需指定名字
import routes from "../assets/routes";
当直接导出一个变量、函数或类时,不需要显式的 return
module.exports 是 CommonJS 模块系统的导出方式,通常用于 Node.js 环境
export 是 ES Module(ESM)的导出方式,是现代 JavaScript 标准的一部分,广泛用于浏览器和前端框架中
Vite 默认支持 ES Module(ESM),并且推荐使用 ESM 的语法(如 export 和 import);使用 ESM 可以更好地与现代工具链集成,例如 TypeScript、Tree Shaking(摇树优化)等