//进入效果。router-enter{opacity:0;}.router-enter-active{transition:opacity1sease;}.router-enter-to{opacity:1;}//leaveeffect.router-leave{opacity:1;}.router-leave-active{transition:opacity1sease;}.router-leave-to{opacity:0;}上一篇讲了动态路由匹配,编程导航,嵌套路由匹配,命名路由,命名视图,路由中的重定向。一个知识点,但是在vue-router官网,不止这些内容,我说的知识点是针对实际项目开发的。如果想进一步了解vue-router,可以参考官网内容回顾上一节的内容。当我们谈到动态路由匹配和程序化导航时,组件如何获取路由传递的值?动态路由匹配:程序化导航:有没有发现,在具体的组件中,我们使用$route.params和$route.query来获取路由传递的参数。如果在其他路由下使用这个组件,当路由没有携带参数时,如果组件中有$route.query.taskId这样的东西,就会报错。因此,使用以上两种方式,当需要组件复用时,由于路由与组件的耦合度很高,无法做到最大化。复用组件,那么就需要使用其他的方法,即路由组件传参路由组件传参路由组件传参路由组件传参也有3种方式实现:第一种方式:布尔方式修改src/router/index中的路由。js:{path:'/task-detail/:taskId',name:'task-detail',component:()=>import('../views/task-detail.vue'),props:true},组件内部获取路由传递的值:这样,当组件需要复用时,如果想把taskId的值传递给组件,只需要调用这个组件通过路由给组件传值时,这样写:任务详情10000217类型2:对象mode只需要修改src/router/index.js中的路由,和组件中的布尔模式一样:{path:'/task-detail',name:'task-detail',component:()=>import('../views/task-detail.vue'),props:{taskId:'10000218'}},通过路由给组件传值时,这样写:taskdetails10000217类型三:function方式只需要修改src/router/index.js中的route,组件中获取的值与上面两种相同:{路径:'/task-detail/:taskId',名称:'task-detail',组件:()=>import('../views/task-detail.vue'),props:route=>{if(route.params&&route.params.taskId){return{taskId:route.params.taskId}}}},通过路由给组件传值时,写this:taskdetails10000217HTML5History模式说这个之前,先介绍一下html中锚点的概念。以我的博客为例。一篇文章很长,超过你电脑一两个屏幕的目录。比如下面这篇文章的内容:Title1。字幕12.字幕23.字幕3...我想快速访问一个字幕的内容,可以写访问字幕1访问副标题1访问副标题1...1.副标题12.副标题23.副标题31.字幕12.副标题23.Subtitle3这是主播的内容,这跟本节的内容有什么关系?vue-router官方说vue-router默认是hash模式,什么是hash?介绍一下:hash属性是一个可读可写的字符串,它是URL的锚点部分(#开头的部分),#代表网页中的一个位置,右边的字符是该位置网址。标识符(即锚点),例如:http://www.blog.com/index.html#title1代表网页index.html的title1位置,浏览器会自动滚动title1位置后读取这个URL可见区域是用来引导浏览器的动作的,对服务器端是完全没有用的,所以,HTTP请求中不包含#,例如访问下面的URL:http://www.blog.com/index.html#title1浏览服务器实际发送的请求是这样的:GET/index.htmlHTTP/1.1Host:www.example.com可以看到只请求了index.html,还有根本没有#title1部分??。因此,在URL中,第一个#后面出现的任何字符都会被浏览器解释为位置标识(定位点),而这些字符将不会被发送到服务器,改变URL中#之后的部分就是只相当于改变锚点。它只会滚动到相应的位置而不会重新加载网页,例如:http://www锚点从.blog.com/index.html#title1到http://www.blog.com/index.html#title2的变化完全由浏览器控制,无需重新向服务器请求index.html页面现在我们回到vue-router的官方文档,里面提到vue-router默认的hash方式(#后面跟一个字符串)使用hash来模拟一个完整的url,所以当url改变时,页面不会重新加载,如果不想这样显示,也可以使用路由历史模式constrouter=newVueRouter({mode:'history',routes})这样,路由会变:http://localhost:4000/#/task-detail/10000216变成http://localhost:4000/task-detail/10000217但是这种模式还需要后端支持,因为我们的应用是单页客户端应用,只有一个index.html页面,当as有变化时,如果使用hash方式,当路由从http://localhost:4000/#/task-detail/10000217变为http://localhost:4000/#/about,直到开始才会重新请求页面最后只有一个index.html页面,路由的变化也可以看做是锚点的变化,相当于浏览器从#/task-detail锚点到/about锚点,但是如果使用历史模式,从路由:http://localhost:4000/task-detail/10000217到http://localhost:4000/about这时候浏览器就会认为需要向服务器请求task-detail.html和about.html。两个html,但是服务器上没有这两个html,就会报404filenotfound错误,所以这时候就需要后端小伙伴的支持了。当匹配不到html页面时,会返回index.html页面,具体后端如何配置,可以参考官方文档navigationguard。这部分是vue-router部分。在实际项目开发中也非常有用。用于判断用户是否已登录或是否有权访问某个页面。它帮助我们在从路由跳转到导航结束的过程中做一些逻辑处理。第一部分我会分几部分讲。一:全局pre-guard查看src/router/index.js中的router。这是vue-router的一个实例。它有一个beforeEach方法。作用是进行全局预保护。让我们看看如何使用它:constroutes=[{path:'/',name:'Home',component:Home},{path:'/about',name:'About',component:()=>import(/*webpackChunkName:"about"*/'../views/About.vue')},{路径:'/task-detail/:taskId',name:'task-detail',component:()=>import('../views/task-detail.vue'),props:route=>{if(route.params&&route.params.taskId){return{taskId:route.params.taskId}}}},{path:'/product',name:'product',component:()=>import('../views/product/index.vue'),children:[{path:'ele-product',//子路由需要在前面加上'/',只有次要路线有名称:'ele-product',组件:()=>import('../views/product/ele-product.vue'),children:[{path:'phone',//子路由需要在前面加上'/',只有次路由有name:'phone',components:{default:()=>import('../views/product/phone.vue'),apple:()=>import('../views/product/apple.vue'),mi:()=>import('../views/product/mi.vue'),vivo:()=>import('../views/product/vivo.vue'),},},{路径:'computer',//子路由需要前面加'/',只有副路由才有name:'computer',component:()=>import('../views/product/computer.vue'),}]}]},...errorRoutes,{path:'*',redirect:'/notFound'}]constrouter=newVueRouter({mode:'history',routes})constwhitelist=['login','error401','error500','notFound','compatible','notLogin','404','abnormal']letapp;router.beforeEach((to,from,next)=>{//constisLogin=!!sessionStorage.getItem('accessToken');constisLogin=trueif(isLogin){if(to.name==='login'){next({name:'home'});}else{next()}}else{if(whitelist.indexOf(to.name)!==-1){next()}else{next({name:'login'})}}});//next()方法一定要加,当然不能跳转router.afterEach((to,from)=>{app=document.querySelector('.app-content-inner')app&&app.scrollTo(0,0)})exportdefaultrouter上面的代码很容易理解,就不一一介绍了,大体逻辑来自本地session拿token看有没有登录,如果登录了直接跳转到首页。如果未登录,请检查当前路由是否在白名单中。就是全局后钩。与前卫不同,这些钩子不会接受下一个函数,也不会改变导航省份。第三种:routeexclusiveguard{path:'/about',name:'About',component:()=>import(/*webpackChunkName:"about"*/'../views/About.vue'),beforeEnter:(to,from,next)=>{if(from.name==='首页'){console.log('从首页跳转')}else{console.log('没有从首页跳转page')}next()}},第四种:组件内部的guardbeforeRouteEnter提到这个的时候,想起前几天在做项目的时候遇到了一个问题。我有一个任务创建页面(http://localhost:8082/#/web-task/task-create),可以从两个页面访问:监控任务列表(http://localhost:8082/#/web-task/web-list)和监控任务管理(http://localhost:8082/#/web-task/task-list)跳转到这里,要求是,从哪个页面跳转,返回哪个页面当任务创建了路由,但是我无法监听到路由的变化。这时候想到了组件中使用guard的beforeRouteEnter,可以gettoandfrombeforeRouteEnter(to,from,next){console.log(to.name)console.log(from.name)console.log(this)//undefinednext()}但是我发现在里面获取不到this的vue实例。解释是因为:在进行这一步的时候,当前组件还没有渲染出来,vue实例也还没有创建,但是非要用怎么办呢?解决方法是给next函数传入一个回调函数就可以完美解决这个问题beforeRouteEnter(to,from,next){next(vm=>{if(from.name==='web_list'){vm.from_router='/web-task/web-list'}elseif(from.name==='task_list'){vm.from_router='/web-task/task-list'}})}beforeRouteLeave关于这个用法,例如,用户当前正在页面上进行编辑操作,保存前跳转到其他页面,那么可以在这个钩子函数中提醒用户编辑未完成,是否取消编辑,这里提醒一下:在这个方法中,你可以直接用这个beforeRouteUpdate//当前路由改变时调用,但组件被重用//例如,对于一个路径/foo/:id动态参数,当在/foo之间跳转时/1and/foo/2,//将呈现相同的Foo组件,因此组件实例将被重用,并且在这种情况下将调用此挂钩。//可以访问组件实例`this`beforeRouteUpdate(to,from,next){console.log('组件被重用')next()}第五路由元信息{path:'/',name:'home',component:Home,meta:{title:'Home',requiresAuth:['admin','user']}},这里的meta是元信息,可以给每个路由对象分配一个title或者键入一个title这里的Flag,用来区分哪些用户可以访问这条路由接下来我讲一个例子,利用前卫和路由元信息修改window.document.title的值首先找到我们在创建的src/lib/util第二段.js,当时说这个文件是用来存放业务相关方法的,然后我们再新建一个方法//util.jsexportconstsetTitle=(title)=>{window.document.标题=标题?title+'-拨测管理平台':'拨测管理平台'}然后在src/router/index.js中导入,在frontguard中添加一行代码//router/index.jsimport{setTitle}from'@/lib/util'router.beforeEach((to,from,next)=>{to.meta&&setTitle(to.meta.title)})第六个转场效果路由切换时,在,我们可以使用组件给它添加一些过渡效果>与我写一个过渡效果的例子://进入效果。router-enter{opacity:0;}.router-enter-active{transition:opacity1sease;}.router-enter-to{opacity:1;}//leaveeffect.router-leave{opacity:1;}.router-leave-active{transition:opacity1sease;}.router-leave-to{opacity:0;}