1.路由守卫
-
全局前置守卫
全局前置守卫的应用场景之一就是在触发路由跳转后,对其拦截判断是否登陆或登陆是否失效,根据判断结果进行处理。
router.beforeEach((to, from, next) => { // 进行逻辑判断,demo const isLogin = localStorage.getItem("isLogin"); // 这里的meta就是下边要说的“路由元信息” if (to.meta.requireLogin) { if (isLogin) { next(); } else { next("/login"); } } else { next(); } if (to.name === "login") { if (isLogin) { router.push({ name: "home" }); } else { next(); } } });
-
全局解析守卫
全局解析守卫在前置守卫后调用:
router.beforeResolve((to, from, next) => { console.log("全局解析守卫", 222); console.log(to); console.log(from); next(); });
需要注意的是,在前置守卫中必须***通过next()放行***之后才能进入组件,才能触发下一阶段钩子。
-
全局后置守卫
后置守卫原理和前置守卫相同,即,在每次路由跳转之后调用。在此钩子中可以设置相应的页面操作,比如页面title、滚动条位置、懒加载结束等操作。不同点是不会改变导航本身,没有next函数。
router.afterEach((to, from) => { // todo })
需要注意的是,后置守卫同样需要在***解析守卫中通过next()放行***后,才能触发后置守卫。
-
路由内守卫
路由内守卫原理同全局前置守卫,却别就是当前***路由内独享***,其他路由不可调用。
{ path: "/getUserList", name: "UserList", component: () => import("@/views/user/userTable.vue"), meta: { requireLogin: false }, beforeEnter: (to, from, next) => { console.log("路由内守卫,路由独享"); console.log(to); console.log(from); next(); // 必须放行 } },
-
组件内守卫
-
beforeRouteEnter
进入组件之前调用,此时没有实例化无法直接调用this。
beforeRouteEnter(to: RouteConfig, from: RouteConfig, next: Function): void { console.log("组件内守卫,进入路由前"); console.log(this); // 进入组件之前未被实例化,无法访问this next((vm: object) => { // 异步打印出vm实例 console.log(vm); }); }
-
beforeRouteLeave
beforeRouteLeave(to: RouteConfig, from: RouteConfig, next: Function): void { // 离开组件前进行确认是否离开 // this 已经可用了,所以不支持传递回调,因为没有必要了 console.log("组件内守卫,离开路由"); console.log(this); // 可以直接使用this next(); }
注意:用了守卫钩子,需要next()放行的地方一定要放行,否则路由无法跳转。通常用来禁止用户在还未保存修改前突然离开。
-
beforeRouteUpdate
beforeRouteUpdate(to: RouteConfig, from: RouteConfig, next: Function): void { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` // this 已经可用了,所以不支持传递回调,因为没有必要了 }
-
-
完整导航解析流程
官方总结的守卫调用顺序。
完整调用流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
-
守卫调用顺序
自己通过demo总结
被官方完整解析流程包含
- 全局前置守卫:对应完整流程3
- 路由内守卫:对应完整流程5
- 组件内:进入路由前:对应完整流程7
- 组件内:离开路由:对应完整流程2
- 全局解析守卫:对应完整流程8
- 全局后置守卫:对应完整流程10
2.路由元信息
配置路由的时候添加一个自定义对象meta,即路由元信息:
{
path: "/getUserList",
name: "UserList",
component: () => import("@/views/user/userTable.vue"),
meta: {
requireLogin: false,
title: "获取用户列表"
}
},
meta还可以放其它信息,比如可以存储该路由相关信息(例如:设置每个路由的title,取路由的title设置为选项卡的标题)
如何在守卫中获取元信息:
router.beforeEach((to, from, next) => {
// to.meta.requireLogin
// to.meta.title
});
3.过渡动效
为组件添加动画效果(内容过多,之后补充)
<transition>
<router-view></router-view>
</transition>
4.数据获取
-
导航完成后获取
完成导航后,在组件生命周期内获取数据(created钩子),此时为了页面友好,需要在获取数据期间显示loading动画进行等待提示。
created () { // 组件创建完后获取数据, // 此时 data 已经被 observed 了 this.fetchData() }
-
导航完成前获取
在为后面的视图获取数据时,用户会停留在当前的界面,因此建议在数据获取期间,显示一些进度条或者别的指示。如果数据获取失败,同样有必要展示一些全局的错误提醒。
beforeRouteEnter (to, from, next) { getPost(to.params.id, (err, post) => { next(vm => vm.setData(err, post)) }) }
5.滚动行为
6.路由懒加载
异步加载组件
const checkbox = () => import("@/views/CheckBoxIndex.vue");
const routes: Array<RouteConfig> = [
{
path: "/checkbox",
name: "Checkbox",
component: checkbox
}
];