前言VueRouter是Vue.js的官方路由管理器。它与Vue.js的核心深度集成,可以轻松构建单页应用程序。包含的功能包括:嵌套路由/视图表模块化、基于组件的路由配置路由参数、查询、通配符基于Vue.js转换系统的视图转换具有自动激活的CSS类的细粒度导航控件自动链接HTML5历史模式或哈希模式IE9下降级自定义滚动条行为本文是笔者实际项目经验总结,主要包括:路由参数变化的响应路由匹配高级匹配方式匹配优先推送和替换路由视图重定向的第二个和第三个参数使用props来解耦$routenavigationguardguardednext方法希望这篇文章对你有所帮助。正文1.响应路由参数变化对于可重用组件(只有路由参数变化),生命周期函数钩子不会被调用,组件如何刷新?watchlistenstowatch:{'$route'(to,from){//对路由变化做出反应...}}beforeRouteUpdatebeforeRouteUpdate(to,from,next){//对路由变化做出反应...//不要忘记调用next()}2。路由匹配{//会匹配所有路径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+'}一个参数multipleParameters//自定义匹配参数//您可以为所有参数提供自定义正则表达式,这将覆盖默认值([^\/]+){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('Component2:beforeCreate');},created(){console.log('Component2:created');}组件间跳转触发onComplete回调。2、组件2跳转到组件2(不带参数)this.$router.push({name:'number'},()=>{console.log('组件2:onCompletecallback');},()=>{console.log('组件2,自跳转:onAbort回调');});组件自跳转无参时触发onAbort回调。但是自跳转带参数的时候,情况可能会有点不一样。3、组件2跳转到组件2(带参数)this.$router.push({name:'number',params:{foo:this.number}},()=>{console.log('组件2:onCompletecallback');},()=>{console.log('Component2,self-jump:onAbortcallback');});组件跳转自带参数,不会触发onComplete回调和onAbort回调。6.路由视图有时希望同时(同级)显示多个视图,而不是嵌套显示。例如,创建一个包含两个视图的布局:sidebar(侧边导航)和main(主要内容)。这时候,命名视图就派上用场了。您可以在界面中有多个单独命名的视图,而不是只有一个插座。如果router-view没有设置名称,则默认为default。一个视图是用一个组件渲染的,所以对于同一条路由,多个视图需要多个组件。确保正确使用组件配置(使用s):constrouter=newVueRouter({routes:[{path:'/',components:{default:Foo,a:Bar,b:Baz}}]});7.redirect{path:'/a',redirect:'/b'}{path:'/a',redirect:{name:'foo'}}{path:'/a',redirect:to=>{/的/方法接收目标路由作为参数//返回重定向字符串路径/路径对象}}注意:Navigationguards不应用于跳转路由,而仅应用于其目标。在上面的示例中,向/a路由添加beforeEach或beforeLeave守卫将没有任何效果。8、使用props解耦$route在组件中使用$route会使其与其对应的路由高度耦合,使得组件只能在某些特定的URL上使用,限制了其灵活性。//路由文件//对于包含命名视图的路由,您必须分别为每个命名视图添加`props`选项:{path:'/number/:name',props:true,//对象模式props:{newsletterPopup:false}//函数模式props:(route)=>({query:route.parmas.name})name:'number',component:()=>import(/*webpackChunkName:"number"*/'./views/Number.vue')}//组件获取exportdefault{props:['name']}9.Navigationguards1.三种全局守卫router.beforeEach在每个全局pre-guard进入路由之前。router.beforeResolve全局解析守卫2.5.0新增。在beforeRouteEnter调用之后调用。router.afterEach全局afterhook进入路由后。//入口文件importrouterfrom'./router'//全局预防护router.beforeEach((to,from,next)=>{console.log('beforeEachglobalpre-guard');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独占路由守卫');下一个();},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/1and/foo/2,//由于将渲染相同的Foo组件,因此组件实例将被重用。在这种情况下将调用此钩子。//你可以访问组件实例`this`console.log('beforeRouteUpdateupdateguardinthecomponent');next();},beforeRouteLeave(to,from,next){//当导航离开组件对应的路由时被调用//可以访问组件实例`this`console.log('beforeRouteLeaveleaveguardinthe成分');next();}组件1跳转到组件2,然后组件2跳转到组件2本身组件1跳转到组件2,然后组件2跳转到组件110。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了,谢谢。如果觉得内容有帮助,可以关注我的公众号,及时了解最新动态,共同学习!