需求:vue 2.0项目,A页面跳转到B页面,再从B页面返回A页面时,A页面能保持之前的状态,不重复刷新。
实现:<keep-alive> 元素将其动态组件包裹起来,失活的组件将会被缓存。注意这个 <keep-alive> 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。
理论只需在项目中做以下修改:
step1: router的meta中添加keepAlive参数,需要缓存则keepAlive为true
{
path: '/parity',
component: () => import('@/views/parity/index'),
name: 'Parity',
meta: {
title: '比价助手',
spm_b_code: 'Parity',
spm_b_name: '比价助手',
keepAlive: true
}
},
step2: app.vue中添加keep-alive
<template>
<div id="app">
<!-- <router-view/> -->
<!-- 可以被缓存的视图组件 -->
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<!-- 不可以被缓存的视图组件 -->
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
<style>
</style>
看了下效果,发现页面A->页面B->页面A,页面A并没有被缓存,于是添加了断点看有没有进入activated和deactivated生命周期。因为正常组件的生命周期和被缓存页面的生命周期是不同。
第一次进入keep-alive组件时,其生命周期执行顺序
beforeRouteEnter --> created --> mounted --> activated --> deactivated
非首次进入时,其生命周期执行顺序:
beforeRouteEnter -->activated --> deactivated
发现进入B页面是,执行完deactivated后,又进入了mounted生命周期,
从B页面回到A页面时,进入mounted,后又进入activated,
相当于组件被重新渲染了两次。
经过查找,发现A页面是二级路由,B页面是一级路由,A页面外还包裹了一层layout,里面也有router-view,于是我们将layout中的router-view也用keep-alive缓存起来:
<template>
<div class="app-wrapper">
<div class="mod_container">
<custom-header />
<keep-alive>
<router-view v-if="$route.meta.keepAlive" :key="routerKey"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="routerKey"></router-view>
<custom-footer />
</div>
</div>
</template>
发现结果一样,还是没有被缓存,又经过一番查找,发现需要在A页面的父级路由中页加入入keepAlive: true。
{
path: '',
component: Layout,
redirect: '/index',
meta: {
keepAlive: true
},
children: [
如此,发现A页面成功被缓存了,由结论可知要缓存二级路由的页面,需要把父级路由也缓存起来。