项目中要求针对某个页面需要添加缓存,于是用到了keep-alive,代码如下:
<keep-alive> <div class="pages"> <router-view v-if="$route.meta.keepAlive" /> </div> </keep-alive> <router-view v-if="!$route.meta.keepAlive" /> 路由配置如下: { path: '/orderTable/:id', component: orderTable, name: 'orderTable', meta: { keepAlive: true // 是否缓存组件 } },
怎末看都不像有问题的样子,但是二次路由切换到orderTable页面时就是不生效,
如果是keep-alive缓存的组件就会有activated
和 deactivated 两个钩子函数,当再次进入缓存的组件页面时,便触发
activated和deactivated函数,不会再触发created和mounted,于是在activated函数里面打断点,当切回时并未进入该函数,说明keep-alive缓存的并不是一个组件,于是顺这个方向查看了源码如下:
........
render () {
const slot = this.$slots.default
const vnode: VNode = getFirstComponentChild(slot) // 获取第一个节点元素
const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions // 判断当前的vnode是不是组件
if (componentOptions) {
// check pattern
const name: ?string = getComponentName(componentOptions)
const { include, exclude } = this
if (
// not included
(include && (!name || !matches(include, name))) ||
// excluded
(exclude && name && matches(exclude, name))
) {
return vnode
}
const { cache, keys } = this
const key: ?string = vnode.key == null
// same constructor may get registered as different local components
// so cid alone is not enough (#3269)
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
: vnode.key
if (cache[key]) {
vnode.componentInstance = cache[key].componentInstance
// make current key freshest
remove(keys, key)
keys.push(key)
} else {
cache[key] = vnode
keys.push(key)
// prune oldest entry
if (this.max && keys.length > parseInt(this.max)) {
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
vnode.data.keepAlive = true
}
return vnode || (slot && slot[0])
}
是不是一下就顿悟了,对于keep-alive缓存的组件,首先会读取第一个节点,然后判断它是不是一个组件,很显然我们在router-view外套了div,对于div它不是一个组件,所以也执行不了接下来的代码,只是将页面渲染了出来而已。
记录一下,谨防再犯,写的不足之处,还望指教