Code前端首页关于Code前端联系我们

不少刚开始用Vue Router搭配TypeScript开发的同学,总会碰到「RouteRecordRaw」这个词,它到底是干啥的?写路由配置时怎么正确用它?今天咱们就把这些疑问掰碎了聊清楚~

terry 9小时前 阅读数 8 #Vue

RouteRecordRaw到底是什么?

简单说,RouteRecordRaw是Vue Router里用来描述「路由记录原始结构」的类型(TypeScript环境下),路由系统要把我们写的路由配置,转换成能识别的规则去匹配URL、渲染组件,RouteRecordRaw就是给这份「原始配置」定规矩的——规定每个路由项得有哪些字段、每个字段是什么格式。

举个例子,你写一个路由对象 { path: '/home', name: 'Home', component: HomeView } ,它的类型就是RouteRecordRaw,要是用TypeScript,定义路由数组时写 const routes: RouteRecordRaw[] = [] ,TypeScript就会帮你检查每个路由项:path格式对不对?name是不是字符串?component有没有正确引入?避免你把component写成components、path写成paths这类低级错误。

不用RouteRecordRaw会怎样?

如果不用这个类型约束,相当于给路由配置“裸奔”,比如你不小心把component写成components,VSCode不会报红提醒,直到运行项目时才发现页面不渲染、路由跳转失效,这时候debug要花很多时间找哪里写错了。

而用了RouteRecordRaw,写代码时TypeScript就像个“实时检查员”,一旦字段名、格式不对,立刻标红提醒,相当于把很多运行时才会暴露的错误,提前到编码阶段解决,能省不少调试精力。

怎么用RouteRecordRaw写路由配置?

下面分几种常见路由场景,看看具体怎么配:

(1)基础静态路由

最基础的路由长这样:

import { RouteRecordRaw } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  }
]

这里要注意3个核心字段:path(路由路径)、name(路由命名,可选但建议写,方便编程式导航)、component(对应的页面组件),RouteRecordRaw会检查这几个字段的类型和格式,比如path必须是字符串,component必须是组件或异步加载函数。

(2)动态路由(带参数)

如果要做用户详情页,需要通过/user/123这种路径传ID,路由配置得这么写:

const routes: RouteRecordRaw[] = [
  {
    path: '/user/:id', // 动态段用:id表示
    name: 'user',
    component: () => import('../views/UserView.vue') // 也可以用懒加载
  }
]

RouteRecordRaw对path的动态参数格式有约束,必须用:参数名的形式,要是你写成/user_id/:id(多了下划线),TypeScript会提示“类型不匹配”,提前拦掉这种格式错误。

(3)嵌套路由(children)

比如有个Dashboard布局页,里面要嵌套Overview、Analysis等子页面,路由得嵌套着写:

const routes: RouteRecordRaw[] = [
  {
    path: '/dashboard',
    component: () => import('../views/DashboardLayout.vue'),
    children: [
      {
        path: 'overview', // 注意:子路由path不用加/,是相对父路由的路径
        component: () => import('../views/OverviewView.vue')
      },
      {
        path: 'analysis',
        component: () => import('../views/AnalysisView.vue')
      }
    ]
  }
]

这里children本身也是RouteRecordRaw的数组,所以每个子路由项也要符合结构要求,而且子路由的path是相对父路由的,比如父路由是/dashboard,子路由写overview,最终匹配的是/dashboard/overview,要是你给子路由path加了(写成/overview),就会变成绝对路径,导致匹配错误,这时候RouteRecordRaw不会拦(因为格式没毛病),但逻辑会错,得自己注意。

(4)重定向(redirect)和别名(alias)

如果要把旧路径重定向到新路径,或者给路径起别名,配置长这样:

const routes: RouteRecordRaw[] = [
  {
    path: '/old-path',
    redirect: '/new-path' // 重定向
  },
  {
    path: '/main',
    alias: '/index' // 别名,访问/index也能打开/main的页面
  }
]

RouteRecordRaw里内置了redirect和alias的类型定义,写的时候要注意字段名别拼错(比如把redirect写成redirct),否则TypeScript会立刻报错。

RouteRecordRaw和路由实例化有啥关系?

当我们用createRouter创建路由实例时,需要传入routes配置:

import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes // 这里的routes必须是RouteRecordRaw[]类型
})

Router构造函数内部会把这些「原始路由记录」(RouteRecordRaw)转换成内部路由对象——处理path解析、组件加载逻辑(比如懒加载的import)、嵌套路由关系等,所以RouteRecordRaw是“原材料”,路由系统加工后变成能工作的“成品”,用来匹配URL、渲染组件。

结合懒加载时要注意啥?

很多项目为了优化首屏加载速度,会用路由懒加载,

component: () => import('../views/AboutView.vue')

RouteRecordRaw对这种异步加载函数的支持很好,类型上是兼容的,但要注意2个点

  • ① 导入路径别写错:比如少写.vue后缀(如果是Vue单文件组件),TypeScript可能不会报错(因为路径解析由Vite/Webpack这类构建工具处理),但运行时会报“找不到模块”,所以写懒加载时,路径要仔细核对,比如确认是../views/AboutView.vue而不是../view/AboutView.vue(少了个s)。
  • ② 动态导入的组件要存在:如果团队协作时,有人删了AboutView.vue文件,TypeScript也没法提前发现(因为是运行时加载),所以最好配合Git钩子、代码审查来避免这种情况。

能给RouteRecordRaw加自定义字段吗?

当然可以!比如我们想给路由加个title(页面标题)、requiresAuth(是否需要登录)这类自定义信息,通常放在meta里:

// 先扩展RouteMeta类型(Vue Router内置的meta类型)
declare module 'vue-router' {
  interface RouteMeta {: string;
    requiresAuth?: boolean;
  }
}
const routes: RouteRecordRaw[] = [
  {
    path: '/profile',
    component: () => import('../views/ProfileView.vue'),
    meta: {
      title: '个人中心',
      requiresAuth: true
    }
  }
]

如果想加meta以外的自定义字段,比如给每个路由加个customTag,可以这样扩展RouteRecordRaw:

declare module 'vue-router' {
  interface RouteRecordRaw {
    customTag?: string;
  }
}
const routes: RouteRecordRaw[] = [
  {
    path: '/special',
    component: SpecialView,
    customTag: 'vip' // 现在可以正常写自定义字段了
  }
]

这样扩展后,TypeScript就允许RouteRecordRaw有customTag字段,既保持类型约束,又满足业务定制需求。

常见错误场景咋解决?

实际开发中,这些错误很常见,提前避坑能省很多事:

(1)字段名拼写错误

比如把component写成components,VSCode会立刻报红:“类型"{ path: string; name: string; components: ... }"不符合RouteRecordRaw的结构”,解决方法很简单——检查字段名,改成正确的component

(2)动态路由参数格式错

如果把/user/:id写成/user_id/:id(多了下划线),TypeScript会提示“类型字符串不符合路由路径规则”,这类错误属于格式问题,修正path的动态段写法就行,比如改成/user/:id

(3)懒加载路径错误

假设要加载AboutView.vue,却写成import('../views/AbotView.vue')(拼写错),TypeScript可能不会报错(因为路径是字符串,TS没法判断文件是否存在),但运行时会404,解决方法是写完路径后,手动检查一遍,或者配合IDE的路径自动补全功能。

(4)嵌套路由path写绝对路径

父路由是/dashboard,子路由写成path: '/overview',这会让子路由匹配/overview而不是/dashboard/overview,导致页面不显示,RouteRecordRaw不会拦这种逻辑错误,所以写嵌套路由时,子路由path别加/ ,保持相对路径。

实战:从0到1配个TS路由

假设现在要新建一个Vue 3 + TypeScript + Vue Router 4的项目,完整的路由配置流程是这样的:

步骤1:安装依赖

打开终端,执行:

npm install vue-router@4

步骤2:创建路由文件

src目录下新建router/index.ts如下:

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
// 引入静态组件
import HomeView from '../views/HomeView.vue'
const routes: RouteRecordRaw[] = [
  // 基础路由
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  // 带命名的路由
  {
    path: '/about',
    name: 'about',
    component: () => import('../views/AboutView.vue') // 懒加载
  },
  // 动态路由
  {
    path: '/user/:id',
    name: 'user',
    component: () => import('../views/UserView.vue')
  },
  // 嵌套路由
  {
    path: '/dashboard',
    component: () => import('../views/DashboardLayout.vue'),
    children: [
      {
        path: 'overview',
        component: () => import('../views/OverviewView.vue')
      },
      {
        path: 'analysis',
        component: () => import('../views/AnalysisView.vue')
      }
    ]
  },
  // 重定向
  {
    path: '/old',
    redirect: '/new'
  },
  // 带meta的路由
  {
    path: '/profile',
    component: () => import('../views/ProfileView.vue'),
    meta: {
      title: '个人中心',
      requiresAuth: true
    }
  }
]
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes
})
export default router

步骤3:在main.ts里挂载路由

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')

这样一套配置下来,每个路由项都被RouteRecordRaw约束着,TypeScript会帮你检查大部分错误,比如要是把component写成components,VSCode会立刻标红,提醒你字段错误。

RouteRecordRaw是路由的“安全网”

对Vue Router+TypeScript项目来说,RouteRecordRaw不是额外的负担,而是保证路由配置规范、减少错误的重要工具,它像个“安全网”,在你写路由时提前拦住字段拼写、格式这类低级错误,让路由系统更稳定。

刚开始接触可能觉得类型约束有点麻烦,但熟悉后会发现——它帮你省的调试时间,远比写类型的那点功夫多,尤其是团队协作时,统一用RouteRecordRaw约束路由配置,能减少很多“为什么我这路由不生效”的沟通成本~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门