Router 的作用是在单页应用(SPA)中将浏览器的URL和用户看到的内容绑定起来。当用户在浏览不同页面时,URL会随之更新,但页面不需要从服务器重新加载。
1 Router 基础
|------------|----------------------------------------------------------------|
| RouterView | RouterView 用于渲染当前URL路径对应的路由组件。可以放在任何地方。 |
| RouterLink | 使得Router能在不重新加载页面的情况下改变URL,处理URL的生成、编码。可以使用router.push()函数来代替。 |
表 Router的基础组件
Router的使用步骤:
- 通过调用createRouter() 函数创建Router实例。参数为一个包含路由数组、history等信息的配置项。
- 将路由器实例注册为插件,通过调用app.use()来完成。
Router插件的职责包括:
-
全局注册RouterView 和 RouterLink组件。
-
添加全局router和route属性。
-
启用useRouter()和useRoute()组合式函数。
-
触发路由器解析初始路由。
<template>Hello App!
<router-view /> </template>import HomePage from "@/views/HomePage.vue";
import {createRouter, createWebHashHistory} from "vue-router";const routes = [
{ path: '/', component: HomePage }
]const router = createRouter({
history: createWebHashHistory(),
routes,
})
export default routerimport { createApp } from 'vue'
import App from './App.vue'
import router from "@/router";const app = createApp(App)
app.use(router)
app.mount('#app')
1.1 动态路由匹配
1.在配置路由列表时,可以配置路径参数,":参数名"的形式。这些参数及值会映射到$route.params 上的相应字段。
|-----------------------------|-----------------------|-------------------------------------|
| 匹配模式 | 匹配路径 | rout.params |
| /user/:username | /user/hmf | { username: 'hmf' } |
| /user/:username/other/:info | /user/hmf/other/hello | { username: 'hmf', other: 'hello' } |
2.可以监听路由参数。
wathc(()=> route.params,(newVal){
// 省略代码,其中route = userRoute()
})
3.在参数中自定义正则表达式。
a)在参数后面的括号里定义该参数匹配的正则表达式。
|-------------|-------------------|---------------------|
| 匹配路径 | /user/:id(\\d+) | /user/:id |
| /user/hello | 不匹配 | 匹配 |
| /user/124 | 匹配 | 匹配,但优先级低于有正则表达式的参数。 |
b) 可重复的参数。如果路径参数值是一个数组,可以用*及+这两个符号将参数标记为可重复:
例如,/user/:ids(\\d+)*,匹配路径/user/123/33/23,route.params 的值为{ids: [123,33,23]}
1.1.1 sensitive 和 strict路由配置
默认情况下,所有路由是不区分大小写的,并且能匹配带有或不带有尾部斜线的路由(例如,匹配模式为/about,非严格模式下,它可以匹配/about/这个路径)。
可以在创建路由器实例时配置sensitive 和 stric。
1.2 路由配置
一些应用程序的UI由多层嵌套的组件组成。在这种情况下,URL的片段通常对应于特定的嵌套组件结构。
实现方式:在组件中包含自己嵌套的<router-view>。例如在User组件的模版内添加一个<router-view>。
<!-- User.vue -->
<template>
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view />
</div>
</template>
对应的路由配置为:
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
path: 'profile',
component: UserProfile,
},
{
path: 'posts',
component: UserPosts,
},
],
},
]
图 嵌套组件及对应匹配的路径
路由配置时,可以给子路由命名(须唯一值),例如:
{path: '/usr', name: 'user', component: UserHome},在路径导航时,不仅可以通过URL来匹配组件,还可以通过子路由命名。
route.push('/usr') 等效于 route.push({name: 'user'})
1.2.1 重定向和别名
{ path: '/home', redirect: '/' }, 从/home 重定向到 /
{ path: '/home', redirect: { name: 'homepage' },从/home 重定向到名为"homepage"的路由。
别名意味着URL不会改变,但是会匹配到特定路径。
{ path: '/', component: Homepage, alias: '/home' },当路径为/及/home时都能访问到Homepage这个组件,且URL不变。
1.2.2 路由组件传参
在组件中使用$route 或useRoute()来获取路径参数,这将使得与路由耦合度更紧密,限制了组件的灵活性,因为它只能用于特定的URL。
可以通过props配置来解除这种行为。在配置路由时,props属性设置为true。
{ path: '/user/:id', component: User, props: true }
<!-- User.vue -->
<script setup>
defineProps({
id: String
})
</script>
<template>
<div>
User {{ id }}
</div>
</template>
还可以创建一个返回props的函数,将参数转换为其他类型。
{
path: '/search',
component: SearchUser,
props: route => ({ query: route.query.q })
}
1.2.3 命名视图
当需要在同级展示多个视图时,可使用命名视图。
<!-- App.vue -->
<template>
<router-view class="view left-sidebar" name="LeftSidebar" />
<router-view class="view main-content" />
<router-view class="view right-sidebar" name="RightSidebar" />
</template>
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
components: {
default: Home,
LeftSidebar,
RightSidebar,
},
},
],
})
图 命名视图
1.2.4 历史记录模式
|----------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| Hash模式 | createWebHashHistory(),它在内部传递的实际URL之前使用了一个哈希字符(#),这使得#后面的URL不会被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理,即可正常访问,但它在SEO中有不好的影响。 例如 http://localhost:8080/#/usr |
| Memory模式 | createMemoryHistory(),不会假定自己处于浏览器环境,因此不会与URL交互也不会自动触发初始导航,不会有历史记录。 |
| HTML5模式 | createWebHistory(),需要在服务器上做配置。 例如 http://localhost:8080/usr,如果没适当配置,会得到一个404错误。 |
表 Vue Router的三种历史模式