1
1
/* @flow */
2
2
3
-
import { isRegExp } from 'shared/util'
3
+
import { isRegExp, remove } from 'shared/util'
4
4
import { getFirstComponentChild } from 'core/vdom/helpers/index'
5
5
6
6
type VNodeCache = { [key: string]: ?VNode };
7
7
8
-
const patternTypes: Array<Function> = [String, RegExp, Array]
9
-
10
8
function getComponentName (opts: ?VNodeComponentOptions): ?string {
11
9
return opts && (opts.Ctor.options.name || opts.tag)
12
10
}
@@ -23,52 +21,62 @@ function matches (pattern: string | RegExp | Array<string>, name: string): boole
23
21
return false
24
22
}
25
23
26
-
function pruneCache (cache: VNodeCache, current: VNode, filter: Function) {
24
+
function pruneCache (keepAliveInstance: any, filter: Function) {
25
+
const { cache, keys, _vnode } = keepAliveInstance
27
26
for (const key in cache) {
28
27
const cachedNode: ?VNode = cache[key]
29
28
if (cachedNode) {
30
29
const name: ?string = getComponentName(cachedNode.componentOptions)
31
30
if (name && !filter(name)) {
32
-
if (cachedNode !== current) {
33
-
pruneCacheEntry(cachedNode)
34
-
}
35
-
cache[key] = null
31
+
pruneCacheEntry(cache, key, keys, _vnode)
36
32
}
37
33
}
38
34
}
39
35
}
40
36
41
-
function pruneCacheEntry (vnode: ?VNode) {
42
-
if (vnode) {
43
-
vnode.componentInstance.$destroy()
37
+
function pruneCacheEntry (
38
+
cache: VNodeCache,
39
+
key: string,
40
+
keys: Array<string>,
41
+
current?: VNode
42
+
) {
43
+
const cached = cache[key]
44
+
if (cached && cached !== current) {
45
+
cached.componentInstance.$destroy()
44
46
}
47
+
cache[key] = null
48
+
remove(keys, key)
45
49
}
46
50
51
+
const patternTypes: Array<Function> = [String, RegExp, Array]
52
+
47
53
export default {
48
54
name: 'keep-alive',
49
55
abstract: true,
50
56
51
57
props: {
52
58
include: patternTypes,
53
-
exclude: patternTypes
59
+
exclude: patternTypes,
60
+
max: [String, Number]
54
61
},
55
62
56
63
created () {
57
64
this.cache = Object.create(null)
65
+
this.keys = []
58
66
},
59
67
60
68
destroyed () {
61
69
for (const key in this.cache) {
62
-
pruneCacheEntry(this.cache[key])
70
+
pruneCacheEntry(this.cache, key, this.keys)
63
71
}
64
72
},
65
73
66
74
watch: {
67
75
include (val: string | RegExp | Array<string>) {
68
-
pruneCache(this.cache, this._vnode, name => matches(val, name))
76
+
pruneCache(this, name => matches(val, name))
69
77
},
70
78
exclude (val: string | RegExp | Array<string>) {
71
-
pruneCache(this.cache, this._vnode, name => !matches(val, name))
79
+
pruneCache(this, name => !matches(val, name))
72
80
}
73
81
},
74
82
@@ -84,16 +92,27 @@ export default {
84
92
)) {
85
93
return vnode
86
94
}
95
+
96
+
const { cache, keys } = this
87
97
const key: ?string = vnode.key == null
88
98
// same constructor may get registered as different local components
89
99
// so cid alone is not enough (#3269)
90
100
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
91
101
: vnode.key
92
-
if (this.cache[key]) {
93
-
vnode.componentInstance = this.cache[key].componentInstance
102
+
if (cache[key]) {
103
+
vnode.componentInstance = cache[key].componentInstance
104
+
// make current key freshest
105
+
remove(keys, key)
106
+
keys.push(key)
94
107
} else {
95
-
this.cache[key] = vnode
108
+
cache[key] = vnode
109
+
keys.push(key)
110
+
// prune oldest entry
111
+
if (this.max && keys.length > parseInt(this.max)) {
112
+
pruneCacheEntry(cache, keys[0], keys, this._vnode)
113
+
}
96
114
}
115
+
97
116
vnode.data.keepAlive = true
98
117
}
99
118
return vnode
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4