最近在做后台项目中遇到一个需求是,pageA跳转pageA编辑页时保留pageA当前状态,pageA跳转pageB时不再保留状态,其实也就是缓存页面问题。于是就拿vue-admin-template为模版进行了测试。

一、添加keepAlive配置
{
path: 'tree',
name: 'Tree',
component: () => import('@/views/tree/index'),
meta: { title: 'Tree', icon: 'tree', keepAlive: true }
}
在meta里添加keepAlive参数用于标示缓存目标页面。
二、router-view添加缓存设置
添加缓存就是把router-view放在标签里即可。
AppMain.vue
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" :key="key" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="key" />
</transition>
</section>
</template>
如上,添加keepAlive判断后就能实现目标页面添加缓存功能。
这时页面会报错,

<template>
<section class="app-main">
<transition-group name="fade-transform" mode="out-in">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" :key="key" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="key" />
</transition-group>
</section>
</template>


<template>
<section class="app-main">
<transition-group name="fade-transform" mode="out-in">
<keep-alive key="aliveItem">
<router-view v-if="$route.meta.keepAlive" :key="key" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="key" />
</transition-group>
</section>
</template>
依旧会报错,keep-alive标签未添加key。查看keep-alive源码可以到,这是因为keep-alive是一个抽象组件,对于抽象组件来说,除了slot属性之外,其他属性在组件内部并没有意义,例如class样式,所以在Vnode层剔除掉多余的属性。
// 创建子组件Vnode过程
function createComponent(Ctordata,context,children,tag) {
// abstract是内置组件(抽象组件)的标志
if (isTrue(Ctor.options.abstract)) {
// 只保留slot属性,其他标签属性都被移除,在vnode对象上不再存在
var slot = data.slot;
data = {};
if (slot) {
data.slot = slot;
}
}
}
······
为了保留动画效果,那就拆开,再改改代码。
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive key="aliveItem">
<router-view v-if="$route.meta.keepAlive" :key="key" />
</keep-alive>
</transition>
<transition name="fade-transform" mode="out-in">
<router-view v-if="!$route.meta.keepAlive" :key="key" />
</transition>
</section>
</template>
测试过后效果还行。这块搞定了,还差点意思,跳转非Table页面时不保存缓存。
views/tree/index.vue
beforeRouteEnter(to, from, next) {
if (from.name !== 'Table') {
to.meta.keepAlive = true
} else {
to.meta.keepAlive = false
}
next()
}
路由进入前做个判断控制就行了。