第7章:路由管理
第19节:路由配置进阶
7.19.1 动态路由与参数
动态路由是指在路由路径中包含动态参数,用于匹配不同的URL但使用相同的组件。
基本用法
const routes = [
// 静态路由
{ path: '/users', component: UsersList },
// 动态路由,:id是动态参数
{ path: '/users/:id', component: UserDetail }
]访问路由参数
在组件中可以通过$route.params或useRoute().params访问路由参数:
<!-- UserDetail.vue -->
<template>
<div>
<h3>用户详情</h3>
<p>用户ID: {{ $route.params.id }}</p>
</div>
</template>
<!-- 使用组合式API -->
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.id) // 访问路由参数
</script>路由参数的类型
可以在路由路径中定义多个参数:
const routes = [
// 多个参数
{ path: '/users/:id/posts/:postId', component: UserPost },
// 可选参数(Vue Router 4.x支持)
{ path: '/users/:id/:name?', component: UserDetail },
// 正则表达式参数
{ path: '/users/:id(\\d+)', component: UserDetail } // 只匹配数字ID
]路由参数变化的处理
当路由参数发生变化时,组件不会重新创建,而是复用现有组件。可以通过以下方式处理参数变化:
- 使用watch监听参数变化:
<script setup>
import { useRoute, watch } from 'vue-router'
const route = useRoute()
watch(
() => route.params.id,
(newId, oldId) => {
// 参数变化时执行的逻辑
console.log(`ID从${oldId}变为${newId}`)
// 重新获取数据
fetchUserData(newId)
}
)
</script>- 使用beforeRouteUpdate导航守卫:
// 选项式API
export default {
beforeRouteUpdate(to, from, next) {
// 参数变化时执行的逻辑
this.id = to.params.id
this.fetchData()
next()
}
}将参数作为props传递
可以通过props选项将路由参数作为props传递给组件,使组件更加解耦:
const routes = [
// 布尔模式:将所有参数作为props传递
{ path: '/users/:id', component: UserDetail, props: true },
// 对象模式:传递固定的props
{ path: '/users/:id', component: UserDetail, props: { admin: false } },
// 函数模式:自定义props
{
path: '/users/:id',
component: UserDetail,
props: (route) => ({
id: route.params.id,
query: route.query,
admin: route.query.admin === 'true'
})
}
]在组件中使用props接收:
<script setup>
// 使用props接收路由参数
const props = defineProps(['id', 'admin'])
console.log(props.id) // 路由参数
console.log(props.admin) // 传递的props
</script>7.19.2 嵌套路由配置
嵌套路由允许在父路由组件中嵌套子路由组件,实现复杂的页面结构。
基本用法
const routes = [
{
path: '/users',
component: UsersLayout,
// 嵌套路由
children: [
// 匹配 /users
{ path: '', component: UsersList },
// 匹配 /users/:id
{ path: ':id', component: UserDetail },
// 匹配 /users/:id/posts
{ path: ':id/posts', component: UserPosts }
]
}
]父组件中需要包含<router-view>来显示子路由组件:
<!-- UsersLayout.vue -->
<template>
<div class="users-layout">
<h2>用户管理</h2>
<nav>
<router-link to="/users">用户列表</router-link>
</nav>
<!-- 子路由视图 -->
<div class="users-content">
<router-view />
</div>
</div>
</template>嵌套路由的参数传递
嵌套路由可以继承父路由的参数:
const routes = [
{
path: '/users/:id',
component: UserLayout,
children: [
// 匹配 /users/:id
{ path: '', component: UserDetail },
// 匹配 /users/:id/posts/:postId
{ path: 'posts/:postId', component: UserPost }
]
}
]在子路由组件中可以访问父路由的参数:
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.id) // 父路由参数
console.log(route.params.postId) // 子路由参数
</script>7.19.3 命名路由与命名视图
命名路由
命名路由允许通过名称引用路由,而不是通过路径,使路由更加灵活:
const routes = [
{
path: '/users/:id',
name: 'user-detail', // 命名路由
component: UserDetail
}
]使用命名路由进行导航:
<!-- 模板中使用 -->
<router-link :to="{ name: 'user-detail', params: { id: 1 } }">用户详情</router-link>
<!-- 组件中使用 -->
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
router.push({ name: 'user-detail', params: { id: 1 } })
</script>命名视图
命名视图允许在同一级路由中显示多个组件:
const routes = [
{
path: '/',
// 命名视图
components: {
default: Home,
sidebar: Sidebar,
header: Header
}
},
{
path: '/about',
components: {
default: About,
sidebar: AboutSidebar,
header: AboutHeader
}
}
]在模板中使用命名视图:
<template>
<div id="app">
<!-- 命名视图:header -->
<router-view name="header" />
<div class="main-content">
<!-- 命名视图:sidebar -->
<router-view name="sidebar" />
<!-- 默认视图 -->
<router-view />
</div>
</div>
</template>7.19.4 重定向与别名
重定向
重定向用于将一个路由重定向到另一个路由:
const routes = [
// 基本重定向
{ path: '/home', redirect: '/' },
// 使用命名路由重定向
{ path: '/home', redirect: { name: 'home' } },
// 动态重定向
{
path: '/users/:id',
redirect: (to) => {
// 根据参数动态重定向
return { path: `/profile/${to.params.id}` }
}
}
]别名
别名允许为路由定义多个路径,访问不同的路径会显示相同的组件:
const routes = [
// 别名:访问 /home 或 / 都会显示 Home 组件
{ path: '/', component: Home, alias: '/home' },
// 多个别名
{ path: '/users', component: Users, alias: ['/people', '/members'] }
]总结
在本节中,我们学习了Vue Router的进阶配置,包括:
- 动态路由与参数:学习了如何定义动态路由,如何访问路由参数,以及如何将参数作为props传递给组件
- 嵌套路由配置:学习了如何创建嵌套路由,实现复杂的页面结构,以及如何处理嵌套路由的参数传递
- 命名路由与命名视图:学习了如何使用命名路由进行导航,以及如何使用命名视图在同一级路由中显示多个组件
- 重定向与别名:学习了如何使用重定向将一个路由重定向到另一个路由,以及如何使用别名定义多个路径访问同一个组件
这些进阶配置使Vue Router更加灵活和强大,可以满足各种复杂的路由需求。通过学习和掌握这些高级功能,你可以构建更加复杂和完整的单页面应用。
在下一节中,我们将学习Vue Router的编程式导航与路由守卫,进一步提高路由的控制能力。