Vue Router是Vue官方的客户端路由解决方案。用于在单页应用中将浏览器的URL和用户看到的内容绑定起来。
使用Vue Router
通过createRouter创建路由器实例
可设置属性有:
linkActiveClass链接激活时使用的CSS类名,默认使用router-link-activelinkExactActiveClass链接被精确匹配时使用的CSS类名,默认使用router-link-exact-activeparseQuery&stringifyQuery编译和解析查询的自定义实现,比如使用qs包对query参数执行 或对路由参数执行加解密操作history指定路由与URL路径是如何双向映射的strict为true时,将禁止尾部斜线sensitive为true时,将区分大小写scrollBehavior在页面之间导航时控制页面滚动,可返回promise设置延时滚动routes应该添加到路由器的初始路由列表
示例 router/index.ts
import {createMemoryHistory, createRouter} from 'vue-router'
const router = createRouter({
linkActiveClass: 'router-link-active',
linkExactActiveClass: 'router-link-exact-active',
parseQuery: (search: string) => LocationQuery,
stringifyQuery: (search: string) => LocationQuery
// 指定路由与URL路径是如何双向映射的
// createMemoryHistory() 会完全忽略浏览器的URL而使用自己内部的URL,其目的是为了处理服务端渲染
// createWebHistory() URL不带#
// createWebHashHistory() URL带#
history: createWebHistory(),
// 为true时,将禁止尾部斜线
strict: true,
// 为true时,将区分大小写
sensitive: true,
// 在页面之间导航时控制页面滚动
scrollBehavior(to, from, savedPosition) {
// 始终滚动到顶部
return { top: 0 }
},
// 应该添加到路由器的初始路由列表
routes: [
{path: '/', component: HomeView}, // 把URL路径映射到组件
...
]
})
然后将路由实例挂载到应用实例上
main.ts
app.use(router)
使用路由后,要在根组件中使用RouterView渲染对应组件
一般在app.vue或者layout/default.vue中,如果是用vue-cli创建项目时自动引用的router,则生成代码中会自动改变,不需要手动修改
<template>
<header>
...
</header>
<RouterView />
</template>
使用router之后会:
- 全局注册
RouterView和RouterLink组件 -
RouterView:可以根据URL路径渲染对应路由组件RouterLink: 能够让Vue Router在不重新加载页面的情况下改变URL,处理URL的生成、编码和其他功能
- 添加全局
$router和$route属性 (在组件模版和选项式API中使用) -
$route:表示当前路由实例$router:表示路由器实例
- 启用
useRouter()和useRoute()组合式函数(在组合式API中使用) -
- 通过
useRouter()可以获取路由器实例:const router = useRouter() - 通过
useRoute()可以获取当前路由实例:const route = useRoute()
- 通过
- 触发路由器解析初始路由
路由匹配
默认情况下,所有路由是不区分大小写的,并且能匹配带有或不带有尾部斜线的路由
-
strict:配置strict: true时,将不会匹配带有尾部斜线的路由 -
sensitive:配置sensitive: true时,将区分大小写// router.ts const routes = [ { // 匹配 /users、 /users/、 /Users/ path: '/users', component: UserCom }, { // 不匹配 /users/ path: '/users', strict: true, component: UserCom }, { // 不匹配 /users/ path: '/users', sensitive: true, component: UserCom }, ]
动态路由
-
带参数的路由:
router.tsconst routes = [ { // 匹配 比如 /detail/34 path: '/detail/:id', component: DetailCom }, { // ?表示可选参数,这里将id标记为可选, 匹配 /detail、 /detail/34 path: '/detail/:id?, component: DetailCom }, ]在组件
DetailCom.vue中获取路由参数const route = useRoute(); const id = route.params.id; // 响应路由参数的变化: // 当从/detail/1跳转到detail/2时,并不会触发组件的生命周期函数 // 此时可以在组件中监听params触发相应逻辑 watch( () => route.params.id, (newId, oldId) => { // 执行具体逻辑 } )
嵌套路由
在一个路由中配置children数组,就是所谓的嵌套路由,相应的RouterView中也要嵌套RouterView
router.ts相关代码
const routes = [
{
path: '/user',
component: UserLayout, // 用户管理的模版组件
children: [
{
path: '',
redirect: '/profile' // 访问/user路径将会重定向到 /user/profile
},
{
// 匹配 /user/profile
path: 'profile',
component: UserProfile, // UserProfile组件将被渲染到UserLayout组件的<RouterView />内部
}
]
},
];
路由跳转
-
router.pushconst routes = [ { path: '/user', name: 'user', component: UserLayout } ] // 以下三种方式是等价的 router.push('/user') router.push({ path: '/user' }) router.push({ name: 'user' }) -
router.replace// 用于替换history中当前路由 router.replace({ path: '/home' }) // 相当于 router.push({ path: '/home', replace: true }) -
在
history中前进或后退// 向前移动一条记录,等同于router.forward() router.go(1) // 后退一条记录,等同于router.back() router.go(-1) // 参数可以是任意数字,如果匹配不到,则静默失败 router.go(100) -
携带参数
-
params// 携带params跳转, 显示在路径上为 /detail/34 router.push({ path: '/detail', params: { id: 34 } }) // 等同于 const id = 34; router.push({ path: `/detail/${id}` }) // detail组件获取params参数 const route = useRoute(); const id = route.params.id; -
query// 携带query跳转,显示在路径上为 /detail?type=typeValue router.push({ path: '/detail', query: { type: 'typeValue' } }) // detail组件获取query参数 const route = useRoute() const type = route.query.type;
-
-
路由组件传参
-
可以通过设置props: true来配置路由将id` 参数作为 prop 传递给组件const routes = [ { path: '/user/:id', component: User, props: true } ] // User组件 const props = defineProps({ id: String }) console.log(props.id);
-
导航守卫
钩子函数都接收to和from入参,表示即将要进入的目标路由和正要离开的路由实例。
原来还会接受一个next入参,该入参已被移除,但仍可用
返回值可以是:
false表示取消当前的导航- 没有返回值(即
undefined)或true表示钩子函数结束,继续当前路由跳转 - 一个路由地址(比如
return '/login')表示路由重定向到指定路由 - 如果意外抛出
Error会取消导航并触发router.onError()注册过的回调函数
KeepAlive & Transition
KeepAlive 组件可以保持路由组件活跃
默认情况下,<KeepAlive>将缓存其中的任何组件实例。我们可以通过 include 和 exclude 属性来自定义此行为。
其中设置的规则匹配的是组件
name,所以需要为组件显式的指定name属性
<!-- comma-delimited string -->
<KeepAlive include="a,b">
<component :is="view" />
</KeepAlive>
<!-- regex (use `v-bind`) -->
<KeepAlive :include="/a|b/">
<component :is="view" />
</KeepAlive>
<!-- Array (use `v-bind`) -->
<KeepAlive :include="['a', 'b']">
<component :is="view" />
</KeepAlive>
可以通过 max 属性缓存的组件实例的最大数量,如果缓存实例的数量即将超过指定的最大计数,则最近访问最少的缓存实例将被销毁,以便为新实例腾出空间。
当组件实例从 DOM 中删除,但它是 缓存的组件<KeepAlive>树的一部分时,它将进入停用状态,而不是被卸载。当组件实例作为缓存树的一部分插入到 DOM 中时,它将被激活。
保持活动状态的组件可以使用 onActivated() 和 onDeactivated() 为这两种状态注册生命周期钩子
Transtition 组件可实现路由组件间切换时实现过渡效果