当前位置: 首页 > 科技观察

10个实际项目中使用的VueRouter进阶技巧

时间:2023-03-13 14:20:41 科技观察

前言VueRouter是Vue.js官方的路由管理器。它与Vue.js的核心深度集成,可以轻松构建单页应用程序。包含的功能有:嵌套路由/视图表模块化、基于组件的路由配置路由参数、查询、通配符基于Vue.js过渡系统的视图过渡效果具有自动激活CSS类的细粒度导航控件链接HTML5历史模式或哈希模式,在IE9中自动降级自定义滚动条行为本文是笔者实际项目经验总结,主要包括:路由参数变化的响应路由匹配高级匹配方式匹配优先推送和替换路由视图重定向的第二个和第三个参数的使用解耦$routenavigationguardguardednext方法的道具希望这篇文章对你有所帮助。正文1.响应路由参数变化对于多路复用组件(只有路由参数变化),生命周期函数钩子不会被调用,如何刷新组件?watch监控watch:{'$route'(to,from){/??/Reacttoroutechanges...}}beforeRouteUpdatebeforeRouteUpdate(to,from,next){//reacttoroutechanges...//don'tforgettocallnext()}2.routematch{//将匹配所有路径path:'*'}{//将匹配任何以`/user-`path:'/user-*'开头的路径}注意:使用通配符路由时,请确保路由的顺序是正确的,也就是说,包含通配符的路由应该放在最后。路由{path:'*'}通常用于客户端404错误。如果您使用历史记录模式,请确保正确配置您的服务器。使用通配符时,名为pathMatch的参数会自动添加到$route.params中。它包含通配符匹配的URL部分://Givearoute{path:'/user-*'}this.$router.push('/user-admin')this.$route.params.pathMatch//'admin'//给路由{path:'*'}this.$router.push('/non-existing')this.$route.params.pathMatch//'/non-existing'3.进阶匹配模式//命名参数必须有一个“单个字符”[A-Za-z09]//?可选参数{path:'/optional-params/:foo?'}//路由跳转可不可以设置foo参数,可选/optional-params/optional-params/foo//零个或多个参数{path:'/optional-params/*'}无参数一个参数多个参数//一个或多个参数{path:'/optional-params/:foo+'}一个参数多个参数//自定义匹配参数//可以是所有参数提供一个自定义正则表达式,它将覆盖默认([^\/]+){path:'/optional-params/:id(\\d+)'}{path:'/optional-params/(foo/)?bar'}4。匹配优先级有时一条路径可能匹配多条路由。此时匹配优先级按照路由的定义顺序:先定义,优先级最高。5.push和replace的第二个和第三个参数在2.2.0+版本中,可选地提供onComplete和onAbort回调作为router.push或router.replace中的第二个和第三个参数。这些回调将在导航成功完成(在所有异步挂钩已被解析之后)或终止(导航到相同的路线,或在当前导航完成之前导航到不同的路线)时被调用。在3.1.0+中,第二个和第三个参数可以省略,如果支持Promise,router.push或router.replace会返回一个Promise。下面看几个例子,看看第二个和第三个参数是什么时候调用的:1.组件1跳转到组件2//组件1this.$router.push({name:'number'},()=>{console.log('Component1:onCompletecallback');},()=>{console.log('Component1:onAbortcallback');});//Component2beforeRouteEnter(to,from,next){console.log('组件2:beforeRouteEnter');next();},beforeCreate(){console.log('组件2:beforeCreate');},created(){console.log('组件2:created');}在组件之间跳转会触发onComplete回调。2、组件2跳转到组件2(不带参数)this.$router.push({name:'number'},()=>{console.log('组件2:onComplete回调');},()=>{console.log('组件2,自跳转:onAbort回调');});当组件无参数自跳转时,会触发onAbort回调。但是自跳转带参数的时候,情况可能会有点不一样。3、组件2跳转到组件2(带参数)this.$router.push({name:'number',params:{foo:this.number}},()=>{console.log('组件2:onCompletecallback');},()=>{console.log('组件2,自跳转:onAbort回调');});组件跳转自带参数,不会触发onComplete回调和onAbort回调。6.路由视图有时希望同时(同级)显示多个视图,而不是嵌套显示。例如,创建一个包含两个视图的布局:sidebar(侧边导航)和main(主要内容)。这时候,命名视图就派上用场了。您可以在界面中有多个单独命名的视图,而不是只有一个出口。如果router-view没有设置名称,则默认为default。一个视图是用一个组件渲染的,所以对于同一个路由,多个视图需要多个组件。确保正确使用组件配置(使用s):construuter=newVueRouter({routes:[{path:'/',components:{default:Foo,a:Bar,b:Baz}}]});7.重定向{path:'/a',redirect:'/b'}{path:'/a',redirect:{name:'foo'}}{path:'/a',redirect:to=>{//method接收目标路由作为参数//返回重定向字符串路径/路径对象}}注意:Navigationguards不应用于跳转路由,而只应用于它们的目标。在上面的示例中,向/a路由添加beforeEach或beforeLeave守卫将没有任何效果。8、使用props解耦$route在组件中使用$route会使其与其对应的路由高度耦合,使得组件只能在某些特定的URL上使用,限制了其灵活性。//router文件//对于包含命名视图的路由,必须为每个命名视图分别添加`props`选项:{path:'/number/:name',props:true,//objectmodeprops:{newsletterPopup:false}//函数模式props:(route)=>({query:route.parmas.name})name:'number',component:()=>import(/*webpackChunkName:"number"*/'./views/Number.vue')}//组件获取exportdefault{props:['name']}9.导航守卫1.三种全局守卫router.beforeEach在每个全局预守卫进入路由之前。router.beforeResolve全局解析守卫2.5.0新增。在beforeRouteEnter调用之后调用。router.afterEach全局afterhook进入路由后。//入口文件importrouterfrom'./router'//全局前卫router.beforeEach((to,from,next)=>{console.log('beforeEach全局前卫');next();});//全局解析守卫router.beforeResolve((to,from,next)=>{console.log('beforeResolve全局解析守卫');next();});//全局后守卫router.afterEach((to,from)=>{console.log('afterEachglobalpostguard');});2.RouteexclusiveguardbeforeEnterglobalfrontguard进入路由前。{path:'/number/:name',props:true,name:'number',//路由独占守卫beforeEnter:(to,from,next)=>{console.log('beforeEnter路由独占守卫');next();},component:()=>import(/*webpackChunkName:"number"*/'./views/Number.vue')}3.守卫beforeRouteEnterbeforeRouteUpdate(2.2new)beforeRouteLeavebeforeRouteEnter(to,from,next){//在渲染组件的对应路由被确认之前调用//否!有能力的!获取组件实例`this`//因为在守卫执行之前还没有创建组件实例console.log('beforeRouteEnter组件进入守卫');next();},beforeRouteUpdate(to,from,next){//当当前路由发生变化时调用,但是组件被复用//比如对于一个带动态参数的路径/foo/:id,当在/foo/1和/foo/2之间跳转时,//因为同一个Foo组件将被渲染,组件实例将被重用。在这种情况下将调用此钩子。//可以访问组件实例`this`console.log('beforeRouteUpdatecomponentupdateguard');next();},beforeRouteLeave(to,from,next){//导航离开对应路由时调用component//可以访问组件实例`this`console.log('beforeRouteLeavecomponentleavesguard');next();}组件1跳转到组件2,然后组件2跳转到组件2本身组件1跳转到组件2、然后组件2跳转到组件110。guardednext方法next:调用方法resolvehook。next():继续执行管道中的下一个挂钩。如果所有的钩子都被执行??,则导航的状态被确认(confirmed)。next(false):中断当前导航。如果浏览器的URL发生变化(可能是用户手动或浏览器的后退按钮),URL地址将被重置为与from路由对应的地址。next('/')或next({path:'/'}):跳转到不同的地址。当前导航被中断并开始新的导航。您可以将任何位置对象传递给next,它允许设置诸如replace:true、name:'home'之类的选项,以及在router-link的toprop或router.push中使用的任何选项。next(error):(2.4.0+)如果传递给next的参数是一个Error实例,导航将被终止,错误将被传递给注册到router.onError()的回调。最后还是希望大家多看文档,理解之后在项目中使用,这样使用后就不会出现BUG了,谢谢。