在做vue项目时,要求用户在访问页面之前先登录,或者在离开页面之前发送提醒。vue-router提供的navigationhook,vue官方提供的路由管理器,通过跳转或者取消来守卫导航。下面总结一下路由钩子函数的使用方法和一些使用场景。1.globalguardrouter.beforeEach在路由变化前钩住constrouter=newVueRouter({...})router.beforeEach((to,from,next)=>{......})where:to:的pathtobeaccessedfrom:表示从哪条路径跳转;next:是一个函数,表示发布。next()的调用有几种方式:如果都正常,则调用该方法进入下一个hook;next(false):中断当前导航,即路由地址不变;next('/xxx')ornext({path:'/xxx'}):强制跳转到指定路径;next(error):如果传入一个Error实例,导航将被中断,错误将被传递给router.onError()注册的回调。使用:使用该函数时,必须调用next(),否则钩子函数无法解析;此方法更常用于:验证用户访问权限。例如:一个系统需要先验证用户是否登录,如果登录了就可以访问,否则直接跳转到登录页面。具体实现如下:importVuefrom'vue'importVueRouterfrom'vue-router'import{getToken}from'@Utils/session.utils'//登录用户的tokenimportLoginfrom'../pages/Login.vue'//引入登录页面constHome=()=>import('../pages/Home.vue')//引入首页Vue.use(VueRouter)//全局注入router//配置路由参数constroutes=[{path:'/login',name:'login',component:Login},{path:'/home',name:'home',component:Home}]constrouter=newVueRouter({routes})//全局挂Routernavigationguard:验证用户是否登录router.beforeEach((to,from,next)=>{if(to.name!=='login'&&!getToken())next('/login')//if如果用户没有访问登录页面,没有登录,则强制跳转到登录页面elsenext()})exportdefaultrouterrouter.beforeResolve导航确认之前,守卫和之后所有组件中的异步路由组件都被解决了,这个钩子函数被调用。这个方法我还没有在项目中使用过,具体使用场景欢迎补充:)router.afterEachHookafterroutechangerouter.afterEach((to,from)=>{......})这个方法和全局pre-guardrouter.beforeEach不同,缺少了next()函数,导航本身不会改变。使用场景:路由切换,将页面的滚动位置返回到顶部。例如:一个页面比较长,滚动到某个位置后切换路由时,跳转页面的滚动条位置默认为上一页离开的位置,滚动条的位置可以通过这个钩子函数重置。//切换路由,页面返回顶部router.afterEach((to,from)=>{window.scrollTo(0,0)})二、路由的独占守卫beforeEnter某条路由的单独守卫,在路由配置中直接定义constroutes=[{path:'/login',name:'login',component:Login},{path:'/home',name:'home',component:Home,beforeEnter:(to,from,next)=>{......}}]constrouter=newVueRouter({routes})使用:该方法参数与全局前卫router.beforeEach相同;例如:根据登录用户为不同的角色显示不同的模块;或者单独给指定的路由组件添加动画。importVuefrom'vue'importVueRouterfrom'vue-router'import{getUserRole}from'@Utils/session.utils'//登录用户的角色constUserCenter=()=>import('../pages/UserCenter.vue')constroutes=[......{path:'/usercenter',name:'usercenter',component:UserCenter,beforeEnter:(to,from,next)=>{if(getUserRole()==='admin')next('/admincenter')elsenext()}}]3.组件中的守卫beforeRouteEnter(to,from,next)调用exportdefault{data(){。。此时被渲染还没有被创建;可以通过给next传递一个回调来访问组件实例,即组件实例vm作为回调方法的参数;回调的执行落后于安装;beforeRouteEnter(to,from,next){next(vm=>{//通过vm访问组件实例})}beforeRouteEnter是唯一支持将回调传递给next的守卫。使用场景:例如:从列表页进入详情页,然后返回列表页。要求保留离开列表页前访问的数据和滚动位置,从其他页面重新进入列表页获取最新数据。具体实现请点击这里beforeRouteUpdate(to,from,next)当当前路由发生变化,但组件被复用时,调用beforeRouteUpdate(to,from,next){......}注:该函数可以访问当前的Component实例this例如:在动态参数为/detail/:id的路由中,在/detail/aaa和/detail/bbb之间跳转时,因为这两个路由渲染的是同一个Detail组件,所以原来的Component实例会是重用(重用比销毁和创建更高效??),这种情况下会调用这个钩子,不会再调用组件的生命周期钩子。beforeRouteLeave(to,from,next)在离开当前组件对应的路由之前,调用beforeRouteLeave(to,from,next){......}注意:该函数可以访问当前组件实例this;当页面有未保存的内容时,突然离开,防止页面跳转并给出提示,或者在用户离开时清除或存储一些信息。4.完整的导航分析流程Navigation被触发;在非活动组件中调用beforeRouteLeave守卫;调用全局beforeEach守卫;在重用的组件中调用beforeRouteUpdate守卫(2.2+);在路由配置中调用beforeEnter;解析异步路由组件;在激活的组件中调用beforeRouteEnter;调用全局beforeResolve守卫(2.5+);导航已确认;调用全局afterEach钩子;触发DOM更新;在beforeRouteEnterguard中调用传递给next的回调函数,创建好的组件实例会作为回调函数的参数传入。其实常用的就那么几个。了解了它们的用法之后,路由导航的分析过程就清楚了。5、附:使用watch监听路由变化除了使用钩子函数,我们还可以使用watch来监听$route对象,然后根据路由参数的变化做出响应。
