当前位置: 首页 > Web前端 > vue.js

VueRouter进阶笔记

时间:2023-03-31 17:57:57 vue.js

1.Navigationguard完成导航解析流程:触发导航在非活动组件中调用beforeRouteLeave调用全局beforeEach在复用组件中调用beforeRouteUpdate在路由配置中调用beforeEnter解析异步路由组件中调用beforeRouteEnter激活的组件,调用全局的beforeResolve导航被确认,调用全局的afterEach触发DOM更新,在beforeRouteEnter守卫中调用传递给next的回调函数,创建的组件实例将作为回调函数的参数传入。参数或查询更改不会触发进入/退出导航守卫。这些更改可以通过观察$route对象或使用beforeRouteUpdate的组件内守卫来处理。1.全局pre-guardrouter.beforeEachconstrouter=newVueRouter({...})router.beforeEach(to,from,next)=>{/*to:Route--要进入的目标路由对象*//*from:Route--当前导航离开的路径*//*next:function--解析这个hook必须调用这个方法。执行效果取决于next方法的调用参数。*/next()/*进行到管道中的下一个钩子。如果所有执行都完成,则导航状态得到确认。*/next(false)/*中断当前导航。如果浏览器的url改变了(可能是用户手动或者浏览器后退),url会被重置为from路由对应的地址。*/next('/')/*同下*/next({path:'/'})/*跳转到不同的地址。*/next(error)/*导航终止,错误被传递给注册到router.onError()的回调。*/}确保下一个函数在任何给定的导航守卫中只被调用一次。可能会出现不止一次,但前提是所有的逻辑路径不重叠,否则永远无法解析钩子或报错。/*BAD*/router.beforeEach((to,from,next)=>{if(to.name!=='Login'&&!isAuthenticated)next({name:'Login'})/*如果用户验证失败identity,那么`next`将被调用两次*/next()})/*GOOD*/router.beforeEach((to,from,next)=>{if(to.name!=='Login'&&!isAuthenticated)next({name:'Login'})elsenext()})2.全局解析守卫router.beforeResolve--类似于router.beforeEachj,不同的是:在确认导航前,在所有组件中守卫在同时并在异步路由组件解析完成后,调用parseguard。3、全局post-hookrouter.afterEach()--nonext(),不会改变导航本身router.afterEach(to,from)=>{//...}路由配置方法:1.独占路由守卫——直接在路由配置上定义beforeEnter守卫constrouter=newVueRouter({routes:[{path:'/user',component:User,beforeEnter:(to,from,next)=>{}}]})2。组件中的守卫可以直接在路由组件中定义如下路由导航守卫beforeRouteEnterbeforeRouteUpdatebeforeRouteLeaveconstFoo={template:`...`,beforeRouteEnter(to,from,next){/*渲染组件对应的路由确认ex-call*//*不能!获取组件实例`this`*//*因为在guard执行之前还没有创建组件实例,可以通过回调给next来访问组件实例,只有guard支持这个方法*/next(vm=>{/*通过vm访问组件实例*/})},beforeRouteUpdate(to,from,next){/*当前路由改变时调用,但组件被复用*//*比如对于一个动态参数路径/foo/:id,在/foo/1和/foo/2之间跳转时*//*由于会渲染同一个Foo组件,所以组件实例会被复用。在这种情况下将调用此钩子。*//*可以访问组件实例`this`*/this.name=to.params.namenext()},beforeRouteLeave(to,from,next){/*离开组件对应的路由时调用*//*可以访问组件实例`this`*//*这个guard可以用来防止用户在保存修改之前突然离开,next(false)可以取消导航*/constanswer=window.confirm('还没有保存,你确定要离开吗')if(answer){next()}else{next(false)}}}2.路由元信息-元路由登录拦截/*1。在需要登录验证的路由中设置meta*/requireAuth值为trueconstrouter=newVueRouter({routes=[{path:'/detail',name:'detail',component:Detail,meta:{requireAuth:true}},{path:'/login',name:'login',component:Login}]})/*2,router.beforeEach()钩子函数,进入每个网页前都会调用,可以做路由拦截在这个钩子函数中*/router.beforeEach((to,from,next)=>{/*判断传入路由是否需要路由拦截*/if(to.matched.some(record=>record.meta.requireAuth){/*vuex.state判断token是否存在*/if(store.state.token){/*登录*/next()}else{next({path:'/login',query:{redirect:to.完整路径}})}}else{next()}})3.过渡动画使用标签包裹标签添加一些过渡效果,在这个router-view中的routes中也会添加同样的效果影响如果想给不同的路由添加不同的效果,可以在路由组件中设置来添加效果constFoo={template:`...

`}constBar={template:`...
`}设置动态转场//...//然后在父组件中//watch$route决定使用哪个transitionwatch:{'$route'(to,from){consttoDepth=to.path.split('/').lengthconstfromDepth=from.path.split('/').length这。transitionName=toDepth{//...})获取url上的数据}}2.在导航前获取数据在要重定向的路由组件中的beforeRouteEnter守卫中获取数据。获取数据成功后,才调用next()方法(err,post)=>{next(vm=>vm.setData(err,post))})},//在路由变化之前,组件已经渲染//逻辑略有不同beforeRouteUpdate(to,from,next){this.post=nullgetPost(to.params.id,(err,post)=>{this.setData(err,post)next()})},方法:{setData(err,post){if(err){this.error=err.toString()}else{this.post=post}}}}5.滚动行为当切换到新路由时,将页面滚动到顶部或保持原来的滚动位置,可以在路由器实例中提供scrollBehavior方法。constrouter=newVueRouter({routes:[...],scrollBehavior(to,from,savedPosition){//返回预期的滚动位置//return{x:number,y:number}//滚动到顶部//return{x:0,y:0}//savedPosition在按下后退和前进按钮时可用if(savedPosition){returnsavedPosition}else{return{x:0,y:0}}}})模拟滚动到AnchorscrollBehavior(to,from,savedPosition){if(to.hash){return{selector:to.hash,//设置平滑滚动行为:'smooth'}}}6.路由延迟加载为了提高加载效率,使用Lazyloading,只有在访问路由的时候才会加载对应的组件。需要结合Vue异步组件和webpack//1将异步组件定义为返回promise的工厂函数。constFoo=()=>{Promise.resolve({//组件定义对象})}//2.使用import引入组件import('./Foo.vue')//import返回一个promise//可以结合两个或者constFoo=()=>import('./Foo.vue')//路由是一样的实例化时正常