面试题:Vue Router 中如何获取路由传递过来的参数?

在 Vue Router 中,获取路由传递的参数是开发中的常见需求。参数主要分为两种:动态路由参数(params查询参数(query。获取方式取决于你使用的 Vue 版本和 API 风格(Options API 或 Composition API)。


一、 参数类型

  1. 动态路由参数 (params)
    • 来源于路由路径中的动态片段。
    • 例如:路由 path: '/user/:id',当访问 /user/123 时,params{ id: '123' }
    • 注意params 只能通过 nameparams 进行导航(router.push({ name: 'user', params: { id: 123 } })),不能通过 path 直接设置(router.push('/user/123') 会丢失 params)。
  2. 查询参数 (query)
    • 来源于 URL 中的查询字符串(? 后面的部分)。
    • 例如:访问 /user?name=john&age=25 时,query{ name: 'john', age: '25' }
    • 可以通过 pathname 导航时设置。

二、 获取参数的方法

方法一:使用 this.$route (Options API – Vue 2 & Vue 3)

在组件的 setup 外部(Options API 风格),通过 this.$route 对象访问当前路由信息。

<script>
export default {
  computed: {
    // 获取动态参数
    userId() {
      return this.$route.params.id
    },
    // 获取查询参数
    userName() {
      return this.$route.query.name
    },
    userAge() {
      return this.$route.query.age
    }
  },
  watch: {
    // 监听动态参数变化(当在同一路由的不同动态值间切换时)
    '$route.params.id'(newId, oldId) {
      if (newId !== oldId) {
        this.fetchUserData(newId)
      }
    },
    // 监听查询参数变化
    '$route.query.name'(newName) {
      this.updateSearchResults(newName)
    }
  },
  methods: {
    fetchUserData(id) {
      console.log('Fetching user:', id)
    },
    updateSearchResults(name) {
      console.log('Searching for:', name)
    }
  },
  created() {
    // 在生命周期钩子中获取
    console.log('Params:', this.$route.params)
    console.log('Query:', this.$route.query)
  }
}
</script>

方法二:使用 useRoute() Composable (Composition API – Vue 3 推荐)

setup() 函数或 <script setup> 中,使用 useRoute() 钩子获取当前路由对象。

<script setup>
import { useRoute } from 'vue-router'
import { ref, watch } from 'vue'

// 获取路由对象
const route = useRoute()

// 响应式地获取参数
const userId = ref(route.params.id)
const userName = ref(route.query.name)
const userAge = ref(route.query.age)

// 监听参数变化(使用 watch 监视 route 对象的特定属性)
watch(
  () => route.params.id,
  (newId, oldId) => {
    if (newId !== oldId) {
      fetchUserData(newId)
    }
  }
)

watch(
  () => route.query.name,
  (newName) => {
    updateSearchResults(newName)
  }
)

function fetchUserData(id) {
  console.log('Fetching user:', id)
}

function updateSearchResults(name) {
  console.log('Searching for:', name)
}

// 在模板中可以直接使用 route.params 和 route.query
</script>

<template>
  <div>
    <h1>User ID: {{ route.params.id }}</h1>
    <p>Name: {{ route.query.name }}</p>
    <p>Age: {{ route.query.age }}</p>
  </div>
</template>

方法三:使用路由 props 传参 (推荐 – 解耦组件)

这是一种更优雅、组件更独立的方式。将路由参数作为 props 传递给组件。

步骤:

  1. 在路由配置中启用 props
// router/index.js
const routes = [
  {
    path: '/user/:id',
    component: UserDetail,
    // 方式1: 布尔模式 - 将 params 映射为 props
    props: true 
  },
  {
    path: '/search',
    component: SearchResults,
    // 方式2: 函数模式 - 灵活地将 params 和 query 都映射为 props
    props: (route) => ({
      id: route.params.id,
      keyword: route.query.q,
      page: parseInt(route.query.page) || 1
    })
  }
]
  1. 在组件中声明 props
<!-- UserDetail.vue -->
<script setup>
// 声明接收来自路由的 props
const props = defineProps({
  id: {
    type: String,
    required: true
  }
})

// 现在可以直接使用 props.id
console.log('User ID:', props.id)
</script>

<template>
  <div>User ID: {{ id }}</div> <!-- 解构后可直接使用 -->
</template>

优点

  • 组件与 vue-router 解耦,可以在任何地方使用。
  • 更易于测试(只需传入 props 即可)。
  • 代码更清晰,依赖关系明确。

三、 获取参数的完整示例

假设路由配置如下:

{
  path: '/article/:id',
  name: 'Article',
  component: Article,
  props: route => ({
    id: route.params.id,
    from: route.query.from,
    category: route.query.category
  })
}

访问 URL:/article/456?from=home&category=tech

获取方式如何获取
this.$routethis.$route.params.id'456'
this.$route.query.from'home'
this.$route.query.category'tech'
useRoute()useRoute().params.id'456'
useRoute().query.from'home'
props在组件中定义 props: ['id', 'from', 'category'],然后使用 this.id, this.from (Options API) 或 props.id (Composition API)

总结

方法适用场景是否推荐
this.$routeOptions API 项目,快速获取参数。✅ 常用,但需注意监听变化。
useRoute()Vue 3 Composition API 项目。Vue 3 推荐方式
路由 props需要组件解耦、提高可测试性和复用性。✅✅ 最佳实践,强烈推荐

核心要点

  • 区分 params(路径参数)和 query(查询字符串)。
  • 在动态路由切换时,必须监听 $routeroute 的变化来更新数据。
  • 优先考虑使用 props 方式,它使组件更纯粹、更易维护。
THE END
喜欢就支持一下吧
点赞7 分享