VUE2 学习笔记17 路由
路由
路由器:router,在日常生活中,路由器的一个接口可以连接一台设备,连接到路由器接口的设备可以上网。路由器可以管理多个路由。
路由:route,是一种对应关系,对应某个地址和实际的设备或页面等,是一种key-value对应。
在前端开发中,路由用于实现单页面应用。
多页面:网站有很多个HTML,当显示不同的页面时,在多个HTML间进行跳转,通常要开多个页签。
单页面:在需要显示不同的页面内容时,页面不进行整个的跳转,只是页面的局部内容进行更新,页面分为导航区和展示区,导航区可以控制当前页面的路由,当路由变化时,展示区会根据路由展示不同的内容。
路由器vue-router会监测浏览器的路由变化,当发现路由变化后,vue-router会去查找路由规则,把找到的路由页面展示在展示区。对于前端来说,路由的key是路径,value是路由对应的组件,这种对应关系就是路由规则。路由规则由router管理。
前端路由:
前端路由,即当前端浏览器中URL发生变化时,引发展示区展示不同的组件。
后端路由:
与前端路由不同,后端路由是以函数的形式进行,是服务器用于处理前端请求的方式。
在后端,比如node.js中,会对请求的路径进行匹配,匹配上后,会执行相应的函数去响应这个请求。
vue-router
vue-router是Vue的一个插件库,可以用来实现SPA(单页面应用)。
安装vue-router:npm i vue-router@3
(在vue2中,使用vue-router3,在vue3中,使用vue-router4)
使用vue-router:在入口文件处,通过import VueRouter from 'vue-router'引入,通过Vue.use(VueRouer)使用。
使用vue-router之后,就可以写router配置项,Vue实例和VueComponent实例上有$route和$router方法。
基本路由配置实现
创建router一般是在src文件夹下创建router文件夹,在router文件夹下的index.js中创建路由配置。
在index.js中引入vue-router。import VueRouer from 'vue-router'。
然后创建一个路由器,并为这个路由器添加配置。最后要对这个router进行暴露。并在入口文件出进行配置。
const router = new VueRouter({
routes:[...]
})
在配置对象中,routes是key,表示配置路由,value是数组,数组中是多个配置对象,对象中path表示配置的URL路径,component表示当前路径下显示的组件。name表示当前路由配置的名字。
配置好路由和对应的组件之后,在页面中,通过<router-link>标签来修改当前页面的URL路径。router-link标签上具有to属性,表示点击标签对应的元素时,跳转的路径。to的value可以写多种形式,其中一种是写routes中配置的key。另一种方法是对to进行动态绑定,value值是相关的配置对象。
现在可以进行路由的改变了,路由改变之后,路由对应的页面在何处进行展示,通过<router-view>标签进行控制。
通过router-link跳转时,Vue最终会把页面内容解析成a标签,除了使用标签进行导航,还可以使用编程式导航,编程式导航使用this.$router方法触发。
引入路由之后,组件分为路由组件和一般组件,路由组件由URL路径控制是否显示,一般不会自己主动引用,其他不由路径控制是否显示的组件,是一般组件。一般会把路由组件和一般组件放在不一样的位置,把路由组件放在pages文件夹中,把一般组件放在components文件夹中。
如果当前展示区从B组件切换成A组件,件会发生什么:当把B组件切走时,会完成B组件的销毁及A组件的挂载。
this.$route:存放当前展示区组件的配置项,对于不同的组件,$rouer中存放的内容是不同的,里面存放的是router配置文件中对应的配置内容。
this.$router:整个项目的路由器,对于不同的组件,$router是一个,上面有各种路由跳转的方法,可以用于编程式路由跳转。
嵌套路由
进入某个路由页面后,在这个路由页面中,也存在自己的导航区和展示区。
如何配置这种嵌套结构:对于组件来说,在具有嵌套路由的组件中,配置子组件,把需要根据路由显示的不同组件进行编写。
在父组件中,配置router-link,实现路由的跳转,在router-link标签中,to属性的value值会有一定的语法变化,当value值直接写配置的path名时,不能直接写二级路由的path,因为to属性只会检索一级路由,要通过一级路由path/二级路由path的格式,来指定要跳转的是二级路由;同样通过<router-view>标签来设置展示区。
在路由配置文件中,通过对配置对象添加children配置项来进行添加,外层的路由叫一级路由,内层children配置的路由为二级路由。children的value是一个数组,数组元素为对象,每一个对象都是一个当前一级路由的子路由,子路由的配置项和一级路由一样,但是在配置子路由的path时,不需要指定完整的路径,只需要配置父组件路由,也就是一级路由URL/后面的部分。路由器会对二级路由的路径进行拼接。
二级路由也可以配置children,形成三级路由。路由可以多层级嵌套,甚至达到五级路由、六级路由。
路由传参
如果展示区的内容与导航区存在关联,导航区会影响展示区的数据,但是展示区的结构是一样的,在进行路由跳转时,可以通过路由传参来控制这种差异,不需要写多个不同的组件来实现。
路由传参有两种方法:query和params。
query
query通过?的形式传递参数,?后的内容就是query参数,query参数以key=value的形式传递,多个key=value之间通过&分隔。
在router-link时,可以通过to设置query。to可以直接写URL字符串,也可以写配置对象。通过query配置要携带的query。
在router-link对应的子组件中,可以通过this.$route.query获取当前URL下传递过来的query,query是一个对象,key是URL中对应的key,value是URL传参时对应的value。
配置query时,不需要修改路由配置。
params
通过params传参时,要修改对应的路由配置。
在router-link中,如果通过to=URL路径字符串的形式携带params,直接以路径的形式写就可以,params在路径上的显示方式就是/params参数,
在进行params传值时,要在路由配置时,设置params的key,否则路由无法识别params的部分是下一级路由还是params参数,在路由配置中,通过/:key,配置params。
在路由进行更新后,在新的URL中,传递的params通过this.$route.params获取,params对象中,key是配置路由时用于占位的/:key,value是URL传递的数据。
如果在router-link的to中,想通过配置对象进行params的传递,写params配置对象即可。但在使用配置对象的语法时,params必须和name一起配置,不能通过path配置的方式指定跳转的路由。
props
在实际开发中,每次都通过this.$route.params或者this.$route.query获取页面传递过来的数据,是十分重复的,在传递路由时,可以通过配置路由的props来解决这个问题。
props需要在路由的配置文件中进行配置,props配置的方式有三种:
props:对象。对象中配置的key:value都会以props形式传给配置props配置项的组件。在这个组件中,通过props:[key名(字符串形式)]来获取传递的数据。使用这种方式时,需要提前在路由配置文件中配置对象,不够灵活。
props:布尔值。props:true。若设置props为true,就会把组件收到的所有params参数,以props的形式传给组件。在组件中,以props:[params的key名(字符串)]形式获取params。使用这种方式,只能获得传递的params,会丢失query。
props:函数。在这种方式中,靠函数的返回值来获取props,在组件中,可以通过props的形式获取函数返回的对象。函数的参数为$route,通过返回一个对象,对象的key是props获取的变量名,对象的value是变量值。在函数中,也可以通过解构获取$route中的数据。
路由和浏览器历史记录
浏览器历史记录是栈的结构,当初始进入网页时,会把网页的网址存入栈。当访问新的URL地址时(通过router-link进行路由跳转时),会把新地址push入栈。栈中有一个指针,指针默认指向最新的数据,当点击后退时,指针会向前查找数据,当点击前进时,指针会向后查找数据,这种模式是push模式。
除了push模式,历史记录还有一种replace模式,replace模式会替换掉栈顶的数据。
router-link默认为push模式,如果想在router-link时开启replace,在router-link标签中添加replace,或者:replace="true",页面URL变化时,就会使用replace模式。
编程式路由导航
除了通过router-link标签触发路由跳转,也可以通过编程触发路由跳转。有时候,用户在页面上的某些交互行为会触发路由跳转,这些交互的结构可能并不是router-link,而且,有时候,可能希望实现延迟跳转等逻辑,通过编程式导航可以解决这些问题。
编程式导航通过this.$router.push、this.$router.replace来编写。使用push进行跳转时,会对历史进行进行push模式的跳转,使用replace方法来进行跳转时,会对历史记录进行replace模式的跳转。
在调用这些方法时,提供配置对象即可。
通过this.$router.back可以实现路由的回退,通过this.$router.forward可以实现路由的前进。
this.$router.go,接收一个数字,表示前进的步数(正数)和回退的步数(负数)。
缓存路由组件
如果在当前路由下,页面上有输入框,用户在输入框中输入了数据,当用户切换导航栏选项时,由于当前的组件被销毁了,如果用户回退回这个页面,之前输入的内容不会被保存,如果在实际开发中,希望用户回退时,仍然能够显示之前输入的数据,可以通过在组件对用的router-view组件中添加keep-alive标签来解决这个问题。
用keep-alive标签把router-view标签包裹起来,并且在keep-alive标签上使用include属性,include可以用来指定对哪个router-view对应的组件使用缓存(有时候,并不希望router-view对应的所有组件都缓存),include中包含的组件名在切走时,都不会被销毁,会保持挂载。不指定include的情况下,所有组件都会被缓存。需要设置多个组件被缓存时,使用:include=[组件名1,组件名2,……]就可以。缓存一个组件时,include=‘组件名’就可以。
和路由相关的生命周期钩子activated、deactivated
除了之前在生命周期中介绍的8个生命周期钩子之前,还有2个和生命周期相关的钩子,这2个钩子和路由相关。
当给组件设置keep-alive缓存时,有时候,希望在切走页面时,停掉页面上的一些需要在beforeDestroy清除的事件,与此同时,还需要保留页面上的数据,但keep-alive只能使数据和事件同时保留,如果想要在组件切走时,停掉事件,可以使用activated()激活钩子、deactivated()失活钩子。
当路由发生变化时,某个组件从不存在于页面上,到通过router-view触发,这个组件上的activated钩子就会被触发。
如果某个组件当前为在router-view上展示的组件,但是被切走了,切走时deactivated钩子就会被触发。
在某个组件涉及router-view展示组件的切换时,可以把mounted钩子中的内容放在activated中,把beforeDestroy中的逻辑放在deactivated中。这样在页面切换时,就能够重新运行逻辑。
实际上,nextTick也是一个生命周期钩子,这三个钩子在Vue生命周期介绍时没有提及。