<keep-alive> < router - view v - if = "$route.meta.keepAlive" > <!-- 这里是会被缓存的路由 --> </ router - view > </ keep - alive > < router - view v - if = "!$route.meta.keepAlive" > <!-- 因为用的是v - if 所以下面还要创建一个未缓存的路由视图出口 --> </ router - view > //router配置 new Router ({ routes : [ { path : 'https://www.jb51.net/' , name : 'home' , component : Home , meta : { keepAlive : true // 需要被缓存 } }, { path : '/:id' , name : 'edit' , component : Edit , meta : { keepAlive : false // 不需要被缓存 } } ] });
Vue2.1.0版本之后:
使用路由元信息的方式,要多创建一个 router-view 标签,并且每个路由都要配置一个元信息,是可以实现我们想要的效果,但是过于繁琐了点。
幸运的是在Vue2.1.0之后,Vue新增了两个属性配合 keep-alive 来有条件地缓存 路由/组件。
新增属性:
include :匹配的 路由/组件 会被缓存
exclude :匹配的 路由/组件 不会被缓存
include 和 exclude 支持三种方式来有条件的缓存路由:采用逗号分隔的字符串形式,正则形式,数组形式。
正则和数组形式,必须采用 v-bind 形式来使用。
缓存组件的使用方式:
<!-- 逗号分隔字符串 --> < keep - alive include = "a,b" > < component : is = "view" ></ component > </ keep - alive > <!-- 正则表达式 ( 使用 `v-bind` ) --> < keep - alive : include = "/a|b/" > < component : is = "view" ></ component > </ keep - alive > <!-- 数组 ( 使用 `v-bind` ) --> < keep - alive : include = "['a', 'b']" > < component : is = "view" ></ component > </ keep - alive >
但更多场景中,我们会使用keep-alive来缓存路由:
<keep-alive include='a'> < router - view ></ router - view > </ keep - alive >
匹配规则:
首先匹配组件的name选项,如果 name 选项不可用。
则匹配它的 局部注册名称 。 (父组件 components 选项的键值)
匿名组件,不可匹配。
比如路由组件没有 name 选项,并且没有注册的组件名。
只能匹配当前被包裹的组件, 不能匹配更下面嵌套的子组件 。
比如用在路由上,只能匹配路由组件的 name 选项,不能匹配路由组件里面的嵌套组件的 name 选项。
文档: <keep-alive> 不会在函数式组件中正常工作 ,因为它们没有缓存实例。
exclude 的优先级大于 include
也就是说:当 include 和 exclude 同时存在时, exclude 生效, include 不生效。
<keep-alive include="a,b" exclude="a"> <!-- 只有a不被缓存 --> < router - view ></ router - view > </ keep - alive >
当组件被exclude匹配,该组件将不会被缓存,不会调用activated 和 deactivated。
组件生命周期钩子:
关于组件的生命周期,是时候放出这张图片了:
这张图片已经讲得很清楚了,很多人这部分也很清楚了,大部分生命周期并不会用到,这里提一下几点:
ajax请求最好放在 created 里面 ,因为此时已经可以访问 this 了,请求到数据就可以直接放在 data 里面。
这里也碰到过几次,面试官问:ajax请求应该放在哪个生命周期。
关于dom的操作要放在 mounted 里面 ,在 mounted 前面访问dom会是 undefined 。
每次进入/离开组件都要做一些事情,用什么钩子:
不缓存:
进入的时候可以用 created 和 mounted 钩子,离开的时候用 beforeDestory 和 destroyed 钩子, beforeDestory 可以访问 this , destroyed 不可以访问 this 。
缓存了组件:
缓存了组件之后,再次进入组件不会触发 beforeCreate 、 created 、 beforeMount 、 mounted , 如果你想每次进入组件都做一些事情的话,你可以放在 activated 进入缓存组件的钩子中 。
同理:离开缓存组件的时候, beforeDestroy 和 destroyed 并不会触发,可以使用 deactivated 离开缓存组件的钩子来代替。
触发钩子的完整顺序:
将路由导航、 keep-alive 、和组件生命周期钩子结合起来的,触发顺序,假设是从a组件离开,第一次进入b组件:
beforeRouteLeave :路由组件的组件离开路由前钩子,可取消路由离开。
beforeEach : 路由全局前置守卫,可用于登录验证、全局路由loading等。
beforeEnter : 路由独享守卫
beforeRouteEnter : 路由组件的组件进入路由前钩子。
beforeResolve : 路由全局解析守卫
afterEach :路由全局后置钩子
beforeCreate :组件生命周期,不能访问 this 。
created :组件生命周期,可以访问 this ,不能访问dom。
beforeMount :组件生命周期
deactivated : 离开缓存组件a,或者触发a的 beforeDestroy 和 destroyed 组件销毁钩子。
mounted :访问/操作dom。
activated :进入缓存组件,进入a的嵌套子组件(如果有的话)。
执行beforeRouteEnter回调函数next。
结语