在单页面应用中,不同组件之间的切换需要通过前端路由来实现。
前端路由
1.key是路径,value是组件,用于展示页面内容
2.工作过程:当浏览器的路径改变时,对应的组件就会显示。
vue-router
的路由作用:将组件映射到路由, 然后渲染出来
主要就是
#
及后面的那部分,#
后的url不会发送到服务器,所以改变 URL 中的 hash 部分不会引起页面刷新onhashchange
事件变化。当hash变化时,读取#
后的内容,根据信息进行路由规则匹配,通过改变 window.location.hash
改变页面路由。改变URL的三种方式
优点
pushState()
和 replaceState()
方法,用来在浏览历史中添加和修改记录,改变页面路径,使URL跳转不会重新加载页面。hashchange
事件的 popstate
事件,但 popstate 事件有些不同:优点
pushState()
和 replaceState()
方法,需要特定浏览器的支持.$router是VueRouter的实例对象,表示整个应用的唯一路由器对象。包含了路由跳转的方法、钩子函数等。
$route是当前路由对象,表示本组件的路由规则,每一个路由都会有一个route对象,是一个局部对象。
- | 描述 | 如何指定跳转的路由 | 如果没有传参 | 可以传参没有要求的值吗 |
---|---|---|---|---|
params参数 | 路径/params参数 | 必须要使用name指定路由 | params是路由的一部分,如果在配置了占位符必须要有 如果这个路由有params传参,但是在跳转的时候没有传这个参数,会导致跳转失败或者页面会没有内容。 | 传递路径上没有的占位符,地址栏上不会显示并且刷新会丢失 |
query参数 | 路径? key1=val1 & key2=val2.... | 1.可以使用name指定路由 2.可以使用path指定路由 | query是拼接在url后面的参数,没有也没关系 | query不会 |
params参数传递的时候,传递了设置占位符接收的参数,地址栏不会显示并且刷新会丢失。
解决办法:可以通过this.$route.params
获取参数保存在本地
vue-router
提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
router.beforeEach()
全局前置守卫,每次导航时都会触发。router.afterEach()
全局后置路由守卫,每次路由跳转完成后。不会接受 next 函数,跳转完成已经进入到组件内了router.beforResolve()
全局解析守卫,在路由跳转前,所有组件内守卫和 异步路由组件 被解析之后触发,它同样在 每次导航 时都会触发。 解析完成后导航被确定,准备开始跳转。beforeRouteEnter()
路由进入组件之前调用,该钩子在beforeEach
和 beforeEnter
之后。beforeCreate
生命周期前触发。beforeRouteUpdate()
this 已经可用了,所以给 next 传递回调就没有必要了。对一个带有动态参数的路径 /foo/:id,在/foo/1 和/foo/2之间跳转的时候,由于会渲染统一的Foo组件,因此这个组件实例会被复用,这个钩子在这种情况下可以被调用。beforeRouteLeave()
离开该组件时被调用,this 已经可用了,所以给 next 传递回调就没有必要了。beforeEnter()
需要在路由配置上定义 beforeEnter 守卫,此守卫只在进入路由时触发,在 beforeEach 之后紧随执行,不会在 params、query 或 hash 改变时触发。进入组件前的调用的顺序 beforeEach()=>beforeEnter()=>beforeRouteEnter()=>beforeResolve()
这个过程不可以使用this,因为组件实例还没有被创建,所以需要利用next函数
完整的导航解析流程
1.导航被触发。
2.在失活的组件里调用 beforeRouteLeave
守卫。
3.调用全局的 beforeEach
守卫。
4.在重用的组件里调用 beforeRouteUpdate
守卫。
5.在路由配置里调用 beforeEnter
。
6.解析异步路由组件。
7.在被激活的组件里调用 beforeRouteEnter
。
8.调用全局的 beforeResolve
守卫。
9.导航被确认。
10.调用全局的 afterEach 钩子。
11.触发 DOM 更新。
12.调用 beforeRouteEnter
守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
keep-alive
可以实现组件缓存,当组件切换时不会对当前组件进行卸载。
keep-alive
标签主要是有include、exclude、max三个属性
include
、exclude
前两个属性允许keep-alive
有条件的进行缓存max
可以定义组件最大的缓存个数,如果超过了这个个数的话,在下一个新实例创建之前,就会将以缓存组件中最久没有被访问到的实例销毁掉。两个生命周期activated/deactivated
,用来得知当前组件是否处于活跃状态。
特殊的卸载/挂载流程:activated/deactivated
缓存管理:LRU(Least Recently Used)最近最少使用是一种淘汰算法
特殊的卸载/挂载流程
由于不能将组件真正的卸载,所以keep-alive是将组件从原容器移动到另外一个假容器中,实现假卸载。挂载的时候从隐藏容器中再搬运到原容器。对应到组件的activated
和deactivated
生命周期
keepAlive会对内部组件(需要被缓存的)进行打标记
vnode.type
值,value为vnode对象
,因为组件的vnode对象中存在对组件实例的引用(vnode.component
)cache
前者用来存缓存组件的虚拟dom集合keys
后者用来存缓存组件的key集合