Vue2 + TS,分路径参数、查询参数、装饰器组件 / Vue.extend 两种写法,同时补充类型约束、监听路由、动态路由取值。
前置说明
Vue2 路由对象:
$route.params:动态路径参数(如/user/:id)$route.query:URL 查询参数(如/user?name=xxx)
1. 基础用法(class 装饰器组件,主流写法)
1.1 获取 query 参数(?key=val)
路由配置:
// router/index.ts import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ routes: [ { path: '/demo', name: 'Demo', component: () => import('@/views/Demo.vue') } ] })访问地址:/demo?name=张三&age=18
组件代码:
<template> <div> <p>姓名:{{ name }}</p> <p>年龄:{{ age }}</p> </div> </template> <script lang="ts"> import Vue from 'vue' import Component from 'vue-class-component' @Component export default class Demo extends Vue { // 直接在生命周期取值,添加类型 name!: string age!: number created() { // query 取值 this.name = this.$route.query.name as string this.age = Number(this.$route.query.age) } } </script>1.2 获取 params 动态路由参数(/:id)
路由配置:
routes: [ { path: '/user/:id', // 动态参数 id name: 'User', component: () => import('@/views/User.vue') } ]访问地址:/user/1001
组件取值:
<script lang="ts"> import Vue from 'vue' import Component from 'vue-class-component' @Component export default class User extends Vue { userId!: number created() { // params 取值 this.userId = Number(this.$route.params.id) } } </script>2. Vue.extend 写法(无装饰器)
import Vue from 'vue' export default Vue.extend({ data() { return { id: 0, username: '' } }, created() { // params this.id = Number(this.$route.params.id) // query this.username = this.$route.query.username as string } })3. 路由参数类型定义(TS 进阶,推荐)
给$route自定义参数类型,消除any警告,提升类型提示。
3.1:扩展 Vue 路由类型
新建src/types/vue-router.d.ts
import 'vue-router' declare module 'vue-router' { interface RouteParams { id?: string } interface RouteQuery { name?: string age?: string } }3.2:组件直接使用
TS 会自动识别参数类型,无需强转:
created() { // params 自带类型 const id = this.$route.params.id // query 自带类型 const name = this.$route.query.name }4. 路由跳转并传参(配套使用)
4.1 传 query 参数
// 编程式导航 this.$router.push({ path: '/demo', query: { name: '李四', age: 20 } })4.2 传 params 参数
必须搭配 name + routes 配置动态参数,path + params 不生效:
this.$router.push({ name: 'User', // 路由配置里的 name params: { id: 1002 } })5. 监听路由变化(同组件路由跳转,组件不刷新)
当路由地址改变但组件复用(如/user/1→/user/2),created/mounted不会重新执行,需要watch监听:
<script lang="ts"> import Vue from 'vue' import Component from 'vue-class-component' @Component({ watch: { // 监听整个路由对象 $route(to) { console.log('新参数:', to.params.id, to.query.name) this.handleRouteParams() } } }) export default class User extends Vue { handleRouteParams() { const id = Number(this.$route.params.id) console.log('当前id:', id) } created() { this.handleRouteParams() // 首次进入执行 } } </script>常见坑 & 注意点
- params 参数永远是 string 类型路由解析后
params值默认字符串,数字务必手动Number()转换。 path + params无效传params只能用name跳转。- 刷新页面 params 丢失params 不会保留在 URL 地址栏,刷新丢失;
query会拼接在地址栏,刷新保留。 - TS 提示 $route 不存在检查路由是否全局挂载、
shims文件是否正常。 - 严格模式下
!非空断言 若参数必传,使用变量!: 类型绕过 TS 空值校验
