A -> B 无缓存
B -> A (A保留了之前的缓存)
C -> A (A无缓存)
方法1(会有bug):使用beforeRouteEnter钩子配合keep-alive(这里需要注意如果一个组件有的时候需要缓存有的时候不需要,那么你在路由配置的时候也应该设置keepAlive为true,然后不需要缓存的路由设置为false就行,如果一开始设置为false第一次缓存的时候页面依然会重新渲染),而且因为在beforeRouteEnter里拿不到组件实例,得通过next获取,而next的时候页面已经渲染完了,所以这里你通过修改meta里的keepAlive也是无效的。需要判断来自的路由然后如果路由不是B就执行以下初始化获取数据的函数
App.vue
<keep-alive>
<router-view v-if='$route.meta.keepAlive' class="child-view"></router-view>
</keep-alive>
<router-view v-if='!$route.meta.keepAlive' class="child-view"></router-view>
A
{
path: '/A',
name: 'A',
meta: {
keepAlive: true
}
}
beforeRouteEnter(to, from ,next) {
next(
(vm) => {
// 如果不是从B来的就重新获取数据
if (form.name !== 'B') {
vm.init()
}
}
)
},
methods: {
init(){
this.getData()
}
},
created(){
this.init()
}
B
{
path: '/B',
name: 'B',
meta: {
keepAlive: false
}
}
方法2:使用beforeRouteLeave,如果进入的不是B就清除缓存keepAlive设为false
A
beforeRouteLeave (to, from, next) {
if (to.name !== 'B') {
this.$route.meta.keepAlive = false
}
next()
},
路由及生命周期触发的完整流程
将路由导航、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。