钩子执行的顺序
当点击切换路由时:
- beforeRouterLeave
- beforeEach
- beforeEnter
- beforeRouteEnter
- beforeResolve
- afterEach
- beforeCreate
- created
- beforeMount
- mounted
- beforeRouteEnter的next的回调
当路由更新时:beforeRouteUpdate
全局钩子
使用全局路由钩子,一定要调用next()
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中
import Router from 'vue-router'
Vue.use(Router)
const router = new Router()
router.beforeEach((to,from,next)=>{
......
next()
})
// 全局解析守卫
router.beforeResolve(to,from){
// 和全局前置守卫类似,区别是在跳转被确认之前,同时在所有组件内守卫和异步路由组件都被解析之后,解析守卫才调用。
}
router.afterEach((to, from) => {
...
// 只接受to和from,不会接受 next 函数也不会改变导航本身
})
路由独享守卫
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home,
beforeEnter: (to, from, next) => {
...
}
}
]
})
组件内的钩子
就是将路由钩子函数写在我们的某个具体路由对象里面
路由守卫应用场景
1、只有当用户已经登录并拥有某些权限时才能进入某些路由
2、一个由多个表单组成的向导 例如注册流程 用户只有在当前路由的组件中填写了满足要求的信息才可以导航到下一个路由
3、当用户未执行保存操作而试图离开当前导航是提醒用户
只针对一个进入某个特定的组件拦截
- beforeRouteEnter
在渲染该组件的对应路由被 confirm 前调用
不能获取 组件实例 “this”
因为当守卫执行前 组件实例还没有创建
场景
没有登录 后台没有返回 token
beforeRouteEnter(to,from,next){
console.log(".....beforeRouteEnter")
}
- beforeRouteUpdate
当前路由改变,但是该组件被复用时调用
例子 对于一个带动态参数的路径 /foo/:id 在 /foo/1 和 /foo/2 之间跳转的时候
由于会渲染同样的FOO 组件 因此组件实例会被复用 而这个钩子就会在这个情况下被调用
可以访问组件实例 this
beforeRouteUpdate(to,from,next){
console.log("beforeRouteUpdate")
}
- beforeRoutLeave
导航离开该组件的对应路由时调用
可以访问组件实例 this
场景: 填写表单数据 没有保存 跳转之前触发
beforeRoutLeave (to,from ,next){
// 导航离开该组件的对应路由时调用
// 可以访问组件的实例 'this'
console.log("beforeRoutLeave ")
}
- 路由元
通过路由元信息 判断该行为 是否需要登录
如果需要登录 则判断 该用户
是否已经登录 或者没有登录
let isLogin = window.localstrage.getItem("key")
// 方式一
if(to.meta.requireAuth){ // 该组件页面是否要登录
if(isLogin){
}else{
next({path:"/login"})
}
}
// 方式二
if (to.meta.requireAuth && !isLogin){
next({path:"/login"})
}else{
next()
}
应用场景:
一、清除当前组件中的定时器
当一个组件中有一个定时器时 在路由进行切换的时候,可使用beforeRouteLeave将定时器进行清楚, 以免占用内存:
beforeRouteLeave (to, from, next) {
window.clearInterval(this.timer) //清楚定时器
next()
二、当页面中有未关闭的窗口,或未保存的内容时,阻止页面跳转
如果页面内有重要的信息需要用户保存后进行跳转 或者弹出框的情况 应该阻止用户跳转
beforeRouteLeave (to, from, next) {
//判断是否弹出框的状态和保存信息与否
if (this.dialogVisibility === true) {
this.dialogVisibility = false //关闭弹出框
next(false) //回到当前页面, 阻止页面跳转
}else if(this.saveMessage === false) {
alert('请保存信息后退出!') //弹出警告
next(false) //回到当前页面, 阻止页面跳转
}else {
next() //否则允许跳转
}
}
三 保存相关内容到Vuex中或Session中
当用户需要关闭页面时 可以将公用的信息保存到session或Vuex中
beforeRouteLeave (to, from, next) {
localStorage.setItem(name, content); //保存到localStorage中
next()
}