Keep-Alive是什么?
- keep-alive是vue的内置组件,是用来包裹动态组件的,它会缓存不活跃的组件,keep-alive是一个比较抽象的组件,它自己不会渲染dom节点,也不会出现在父组件链中。
Keep-Alive的功能?
- 在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
keep-alive的属性exclude
- 因为我们在做某个项目的时候不希望某个页面一直重复加载加载这时就需要用到exclude(不允许某个组件缓存)这个属性也叫黑名单
<keep-alive exclude="alive1">
<component :is="name"></component>
</keep-alive>
1. 字符串设置(以逗号分隔)
<keep-alive :exclude="/alive1|alive2/">
<component :is="name"></component>
/keep-alive>
2. 正则表达式
<keep-alive :exclude="/alive1|alive2/">
<component :is="name"></component>
</keep-alive>
3. 数组
<keep-alive :exclude="[alive1,alive2]">
<component :is="name"></component>
</keep-alive>
keep-alive的属性include
- 这个属性和上面的恰恰相反,这个属性意思是只允许某个组件缓存也叫白名单
<keep-alive include="alive1">
<component :is="name"></component>
</keep-alive>
1. 字符串设置(以逗号分隔)
<keep-alive include="alive1,alive2">
<component :is="name"></component>
</keep-alive>
2. 正则表达式
<keep-alive :include="/alive1|alive2/">
<component :is="name"></component>
</keep-alive>
3. 数组
<keep-alive :indclude="[alive1,alive2]">
<component :is="name"></component>
</keep-alive>
- *数组和正则必须使用v-bind ‘:’
- 这样就可以做到某个组件不缓存
keep-alive的属性max
- 这个属性传递的是number类型,意味着最多可以缓存几个组件;
<keep-alive :max="10">
<component :is="name"></component>
</keep-alive>
代码分析
export default {
name: 'keep-alive',
abstract: true,
props: {
include: patternTypes,
exclude: patternTypes,
max: [String, Number]
},
created () {
this.cache = Object.create(null)
this.keys = []
},
destroyed () {
for (const key in this.cache) {
pruneCacheEntry(this.cache, key, this.keys)
}
},
mounted () {
this.$watch('include', val => {
pruneCache(this, name => matches(val, name))
})
this.$watch('exclude', val => {
pruneCache(this, name => !matches(val, name))
})
},
render () {
const slot = this.$slots.default
const vnode: VNode = getFirstComponentChild(slot)
const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
if (componentOptions) {
const name: ?string = getComponentName(componentOptions)
const { include, exclude } = this
if (
(include && (!name || !matches(include, name))) ||
(exclude && name && matches(exclude, name))
) {
return vnode
}
const { cache, keys } = this
const key: ?string = vnode.key == null
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
: vnode.key
if (cache[key]) {
vnode.componentInstance = cache[key].componentInstance
remove(keys, key)
keys.push(key)
} else {
cache[key] = vnode
keys.push(key)
if (this.max && keys.length > parseInt(this.max)) {
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
vnode.data.keepAlive = true
}
return vnode || (slot && slot[0])
}
}