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

【vue】Vue-Router路由管理

时间:2023-03-31 20:02:54 vue.js

Vue-Router路由管理基本使用高级1基本安装和基本使用动态路由嵌套路由程序化导航命名路由命名视图重定向和别名路由组件传递参数历史模式模块1.1安装和基本使用//安装npminstallvue-router--save//引入importVueRouterfrom'vue-router'Vue.use(VueRouter)//这样的话,vue实例上会多出`$的route`和`$router`的两个属性创建两个页面//About.vue//Detail.vue配置路由//router.js文件importVueRouterfrom"vue-router";importAboutfrom'./pages/About'importDetailfrom'./pages/Detail'exportconstrouter=newVueRouter({routes:[{path:'/about',component:About,},{path:'/detail',component:Detail}]})VueRouter引入并实例化,引入组件配置对象的routes选项为一个数组——以对象的形式注册路由,包括路径和组件在mian.js中导入路由实例并注册//mian.jsimport{router}from'./router'newVue({router,render:h=>h(App),}).$mount('#app')//此时可以观察$router和$route的相关配置。在App.vue中使用路由router-link为路由入口,在to配置路径router-view作为路由出口,重定向页面显示在这里类似于一个动态组件,实现了基本的跳转功能,路由功能更加强大。$router类似于$store。根实例注册后,子组件可以访问原来的路由实例,不需要在子组件中频繁引入$route为当前路由1.2动态路由根据不同的路径参数跳转到同一个组件,显示不同的数据//router.js{path:'/about:id',component:About,},//App.vue//About.vue添加到router中注册的路径:param跳转可以使用router-link或者$router。push,跳转路由中携带参数的路由可以通过$route.params访问动态路由的参数,然后根据参数请求数据,然后渲染页面:,对应的定义是params参数?=&,可以定义查询参数,通过$route.query访问user1
通配符捕获所有路由或者404Notfoundroutes{//匹配所有路由path:'*'}{//匹配任何以'/user'开头的路径path:'/user-*'}使用通配符路由时,$route.params会添加一个名为pathMatch的参数包含URL通配符匹配的部分//router.js{path:'*',component:()=>import('./pages/Notfound')}当重定向路径匹配失败时,可以匹配通配符路径,并且通过pathMatch参数使用'/user-*'提示路径错误,可以设置在特定路径下找不到某个页面的提示信息。多级路由的设置路由注册时添加children属性//router.js{path:'/about',component:About,children:[{path:'child',component:()=>import('./pages/Child')}]},//跳转二次跳转子路由路径前不需要/,否则会被认为如下路径开始1.4程序化导航除了使用router-link声明方式创建跳转标签外,还可以使用router的实例方法以编程方式实现跳转推送:向历史栈中添加一条新记录,你可以点击浏览器的返回上一个URLreplace:替换当前历史最高记录go(n):前进或后退|n|步,负数表示后退,正数表示前进,如果记录不够,则this.$router.push({path:"/detail",//params:{userId:123},query:{user:"张三"},});push中的数据可以是对象的形式,params参数不能和路径同时使用,在router-link中也支持对象形式。可以使用name属性传递params参数params参数:参数name必须加在路径中,跳转时使用name属性查询参数:注册时不需要在路径中加信息,它跳转的时候使用path和name都可以。当路径中添加了参数,但是跳转时没有传递params参数,会跳转失败。使用name属性时,支持同时传递params和查询参数1.5命名路由上面介绍了一些名称,可以简化路径过长的问题,避免params参数的问题。routes:[{path:'/user/:userId',name:'user',component:User}]1.6router-view可以添加name属性,对应路由中的组件可以是对象的形式注册路由时,包含多个组件,提供key选择名称//router.js{name:'detail',path:'/detail/:userId',components:{default:Detail,a:()=>import('./pages/Ads')}},//查看没有name属性的视图,使用默认组件1.7重定向和别名重定向访问'/a'redirect'/b',URL和匹配的路由被替换为'/b'//pathroutes:[{path:'/a',redirect:'/b'}]//命名路由:[{path:'/a',redirect:{name:'foo'}}]//动态方法路由:[{path:'/a',redirect:to=>{//该方法接收目标路由作为参数//返回字符串路径/重定向路径Object}}]返回hom时可以将根路径重定向到子路由路径e页面,确保页面填充了别名'/a'的别名'b',访问'/b'时,URL仍然是'/b',但是路由匹配'/a',这相当于访问'/a',只是名称不同。routes:[{path:'/a',component:A,alias:'/b'}]可以自由映射UI结构到任意URL,无限制和配置的嵌套路由结构组件和对应的路由是高耦合的,导致组件只能在特定的URL上使用,限制了灵活性在Detail中使用props属性解耦组件和路由//objectform{name:'detail',path:'/detail',component:Detail,props:{foo:'a',bar:'b'}}组件,静态数据在props中声明后可以直接以对象的形式传递,在配置时写入,使用场景较少//布尔形式{...props:true,}//多个components{...components:{Detial,Ads},props:{Detail:true,Ads:false}}路由跳转到组件时传递params参数,在组件的props中声明并使用//函数形式{...props($route){return{id:$route.params.userId,name:$route.query.user}}}//解构赋值的简写——类似于vuex动作中的context对象{...props({params,q??uery}){return{id:params.userId,name:query.user}}}在不使用props的情况下,所有传递的参数都在url上,需要使用计算属性使用props来一一获取函数形式,params和查询参数以及静态数据可以在组件中的props中声明,简化了取值和解耦的操作1.9History模式下Router中的配置除了需要其他选项路线选项。比如modemode默认是hash,地址栏会有一个#,当url改变时,页面不会重新加载,改为正常的url形式,使用mode:'history'historymode需要一定的后台支持,否则会出现404,因为hash模式#后面的地址作为路由跳转,不会发起http请求,但是在history模式下,当页面刷新时,会发起http请求。由于没有#分隔,所以会把整个地址作为请求地址nginxlocation/{try_files$uri$uri//index.html;}Node.jsconsthttp=require('http')constfs=require('fs')cosnthttpPort=80http.createServer((req,res)=>{fs.readFile('index.html','utf-8',(err,content)=>{if(err){...}res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'})res.end(content)})}).listen(httpPort,()=>{console.log('Serverlisteningon:http://loaclhost:%s',httpPort)})可以在节点。使用js中的connect-history-api-fallback插件可以快速解决history模式后端地址和前端路由地址冲突,导致请求失败。2.10Modules当嵌套路由层级过多时,可以拆分成多个模块,和vuex的拆分方式类似,不需要创建module数组,导入后在routes数组中注册//index即可routers文件夹中的.js入口文件importVueRouterfrom'vue-router'import{about}from'./modules/about'import{detail}from'./modules/detail'import{Notfound}from'./Notfound'exportconstrouter=newVueRouter({routes:[{path:'/'},about,detail,Notfound]})修改为模块化后,需要在main.js中重新引入注册2高级路由guard路由元信息过渡动态数据获取滚动行为路由懒加载导航失效2.1之前全局路由guard设置guardsGlobalparsingguardsGlobalpost-hookroutingExclusiveguards组件中guards的整体流程2.1.1全局pre-guardsbeforeEachconstrouter=newVueRouter({})router.beforeEach((to,from,next)=>{})to:targetroutefrom:exitroutenext:release函数,不带参数直接跳转到目标路由next(false)打断当前导航next('/')ornext({path:'/'})指定路由跳转,你可以使用name和其他选项next(error)中断当前导航,并将Error实例传递给router.onError()来执行回调。next函数只能调用一次。直接到登录页面router.beforeEach((to,from,next)=>{if(to.name!=='login'&&to.name!=='register'&&!isAuthenticated){next({name:'login'})}else{next()}})如果跳转使用的push方法,被守卫拦截重定向后会报错,但不影响使用。push后可以使用catch捕获错误2.1.2全局解析guardbeforeResolve类似beforeEach区别:在确认导航前,解析完所有组件中的guard和异步路由组件后调用解析guard2.1.3全局posthookafterEach与guard不同的是没有nextreleasefunctionrouter。(to,from)=>{//...})2.1.4RouteExclusiveGuardbeforeEnter与全局的不同的是,它作为一个路由配置项,单独控制一条路由。routes:[{path:'/foo',component:Foo,beforeEnter:(to,from,next)=>{//...}}]to:跳转到当前路由from:从某个路由跳转到限制from可以跳转到TheRouting2.1.5组件的地方innerguard作为组件中的一个配置选项beforeRouteEnter:类似于exclusiveguard,在组件实例创建之前被调用,所以无法获取到vm实例。可以在next中添加一个回调函数来访问组件实例beforeRouteEnter(to,from,next){next(vm=>{//通过`vm`访问组件实例})}component被复用,可以访问from的routing组件实例,当this代表此时的vm实例beforeRouteLeave:leavethecomponent对应route时调用,可以访问componentvminstance可以在离开前判断component中的内容,并确认是否离开2.1.6总体流程2.2路由元信息元配置项,在连续的路由嵌套中存储路由元信息,每一层的路由信息??都会被收集到$route.matched数组中。可以使用数组遍历的方式遍历匹配到的数组来查看meta字段。router.beforeEach((to,from,next)=>{if(to.matched.some(record=>record.meta.requiresAuth)){//此路由需要授权,检查是否登录//如果没有,重定向到登录页面。if(!auth.loggedIn()){next({path:'/login',query:{redirect:to.fullPath}})}else{next()}}else{next()//一定要调用next()}})2.3转场动画router-view是最基本的动态组件相当于component标签,所以可以用transition标签包裹起来实现转场效果。同样使用keep-alive实现组件缓存。transition和keep-alive2.4数据的获取往往伴随着路由跳转时从服务器获取数据导航完成后的请求:当导航完成后,在组件的生命周期钩子中请求数据请求完成时会显示“正在加载”提示。使用v-if条件渲染加载页面、错误页面和请求成功页面。在创建的钩子中请求数据。导航完成前请求:获取routeguard中的数据,获取成功后执行导航。在beforeRouteEnter中请求数据,在next()回调中配置request获取的数据2.5ScrollBehavior配置选项切换到新路由时,页面滚动到顶部或保持原滚动位置constrouter=newVueRouter({routes:[...],scrollBehavior(to,from,savedPosition){//返回你期望滚动到哪个位置}})默认不发生滚动,返回svaedPosition时,forward/backward与浏览器原生操作一致return{x:0,y:0}直接根据坐标滚动meta:{x:0,y:0}return{selector:to.meta,behavior:'smooth'}根据meta信息进行平滑滚动returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve({x:0,y:0})},500)})可以返回一个Promise,滚动信息传入resolve来实现异步滚动2.6路由延迟加载异步组件//异步组件工厂函数constAsyncComponent=(url)=>({//需要加载的组件(应该是一个`Promise`对象)component:import(url),//加载异步组件时使用的组件loading:LoadingComponent,//的加载失败时使用的组件error:ErrorComponent,//显示组件加载时的延迟时间。默认值为200(毫秒)delay:200,//如果提供了超时,组件加载也超时,//使用加载失败时使用的组件。默认值为:`Infinity`timeout:3000})使用import()函数异步导入组件,可以在第一次渲染时不下载部分组件,访问异步组件时再下载2.7Navigationfailure路由导航时失败,可以push后链处理错误信息isNavigationFailure(failure,NavigationFailureType)NavigationFailureTyperedirected:调用next(newLocation)重定向到其他地方aborted:调用next(false)中断本次导航canceled:当前导航之前未完成还有一个Newnavigationduplicated:navigationblockedbecausewearealreadyatthedestinationimportVueRouterfrom'vue-router'const{isNavigationFailure,NavigationFailureType}=VueRouter//tryingtoaccesstheadminpagerouter.push('/admin').catch(failure=>{if(isNavigationFailure(failure,NavigationFailureType.redirected)){//向用户显示一个小通知showToast('登录以访问管理面板')}})//尝试访问管理页面路由器。push('/admin').catch(failure=>{if(isNavigationFailure(failure,NavigationFailureType.redirected)){failure.to.path//'/admin'failure.from.path//'/'}})