面试题:如何定义 Vue 的动态路由?如何获取传过来的动态参数?

这是一个关于 Vue Router 的核心知识点。以下是详细的解答:

如何定义 Vue 的动态路由?

在 Vue Router 中,动态路由(Dynamic Routing)是指路由路径中包含可变部分(通常是 ID 或其他标识符),使得一个路由规则可以匹配多个相似的 URL。

定义方法:

在定义路由规则时,使用冒号 : 后跟一个参数名来表示路径中的动态片段。

步骤:

  1. 安装并引入 Vue Router
    确保你已经安装了 vue-router 并在项目中正确引入。
  2. 在路由配置中定义动态路径
    routes 数组中,将路径中可变的部分用 :parameterName 的形式表示。

示例代码:

// router/index.js (或 router.js)
import { createRouter, createWebHistory } from 'vue-router'
import UserDetails from '../views/UserDetails.vue'
import ProductDetail from '../views/ProductDetail.vue'

const routes = [
  // 定义一个动态路由,匹配 /user/任意用户名
  {
    path: '/user/:username', // :username 是动态参数
    component: UserDetails
  },
  // 定义一个动态路由,匹配 /product/任意产品ID
  {
    path: '/product/:id',
    component: ProductDetail
  },
  // 更复杂的例子:多个动态参数
  {
    path: '/category/:categoryName/product/:id',
    component: ProductDetail
  },
  // 可选参数(Vue Router 4+)
  {
    path: '/optional/:optionalParam?',
    component: OptionalView
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

说明:

  • /user/:username 可以匹配 /user/john/user/mary 等。
  • /product/:id 可以匹配 /product/123/product/abc 等。
  • 参数名(如 username, id)是自定义的,用于在组件中引用。
  • 动态参数默认是必需的。如果需要可选参数,可以在参数名后加 ?(如 :id?)。

如何获取传过来的动态参数?

在匹配到动态路由的组件中,有多种方式可以获取动态参数的值。

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

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

<!-- UserDetails.vue (Options API) -->
<template>
  <div>
    <h1>用户详情</h1>
    <p>用户名: {{ username }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    username() {
      // 通过 this.$route.params.参数名 获取动态参数
      return this.$route.params.username
    }
  },
  watch: {
    // 监听路由参数变化(当用户在相同组件的不同动态路由间切换时)
    '$route.params.username'(newUsername, oldUsername) {
      if (newUsername !== oldUsername) {
        this.fetchUserData(newUsername)
      }
    }
  },
  methods: {
    fetchUserData(username) {
      // 根据新的用户名获取数据
      console.log('Fetching data for:', username)
    }
  }
}
</script>

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

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

<!-- UserDetails.vue (Composition API) -->
<template>
  <div>
    <h1>用户详情</h1>
    <p>用户名: {{ username }}</p>
  </div>
</template>

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

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

// 直接解构获取参数
// const { username } = useRoute() // 也可以这样写

// 使用 ref 响应式地获取参数
const username = ref(route.params.username)

// 监听参数变化
watch(
  () => route.params.username,
  (newUsername, oldUsername) => {
    if (newUsername !== oldUsername) {
      fetchUserData(newUsername)
    }
  }
)

function fetchUserData(username) {
  console.log('Fetching data for:', username)
}
</script>

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

这是一种更优雅的方式,可以将路由参数作为组件的 props 传递,使组件与 vue-router 解耦,更易于测试和复用。

步骤:

  1. 在路由配置中启用 props
    const routes = [
      {
        path: '/user/:username',
        component: UserDetails,
        props: true // 启用 props 模式,自动将 params 映射为 props
      },
      {
        path: '/product/:id',
        component: ProductDetail,
        props: route => ({ id: route.params.id, query: route.query.q }) // 自定义 props 函数
      }
    ]
  2. 在组件中像普通 props 一样接收
    <!-- UserDetails.vue (使用 Props) -->
    <template>
      <div>
        <h1>用户详情</h1>
        <p>用户名: {{ username }}</p>
      </div>
    </template>
    
    <script setup>
    // 声明接收来自路由的 props
    const props = defineProps({
      username: {
        type: String,
        required: true
      }
    })
    
    // 现在 username 可以直接作为 props 使用
    console.log('Username prop:', props.username)
    </script>

优点:组件不再依赖 vue-router,可以在任何地方使用,提高了可测试性和复用性。


总结

问题解答
如何定义动态路由?routes 配置的 path 中使用 :parameterName 的语法,例如 path: '/user/:id'
如何获取动态参数?1. this.$route.params (Options API)
2. useRoute().params (Composition API)
3. 路由 props (推荐,解耦组件与路由)

最佳实践建议

  • 对于简单的场景,useRoute() 是 Composition API 下的直接选择。
  • 对于需要组件复用或更好可测试性的场景,强烈推荐使用 props: true 或自定义 props 函数的方式。
THE END
喜欢就支持一下吧
点赞8 分享