mirror of https://github.com/vuejs/core.git
57 lines
1.2 KiB
TypeScript
57 lines
1.2 KiB
TypeScript
// Used for memoizing trees inside render functions.
|
|
//
|
|
// Example (equivalent of v-once):
|
|
//
|
|
// render() {
|
|
// return memoize(h('div', this.msg), this, 0)
|
|
// }
|
|
//
|
|
// Memoize baesd on keys:
|
|
//
|
|
// render() {
|
|
// return memoize(h('div', this.msg + this.count), this, 0, [this.msg])
|
|
// }
|
|
|
|
// TODO how does this work in v-for?
|
|
// probably need to take vnode key into consideration
|
|
|
|
import { Component } from '../component'
|
|
import { warn } from '../warning'
|
|
|
|
const memoizeMap = new WeakMap()
|
|
|
|
export function memoize<T>(
|
|
getter: () => T,
|
|
instance: Component,
|
|
id: number,
|
|
keys?: any[]
|
|
): T {
|
|
if (__DEV__ && arguments.length > 3 && !Array.isArray(keys)) {
|
|
warn(
|
|
`keys passed to v-memo or memoize must be an array. Got ${String(keys)}`
|
|
)
|
|
}
|
|
let storage = memoizeMap.get(instance)
|
|
if (!storage) {
|
|
storage = []
|
|
memoizeMap.set(instance, storage)
|
|
}
|
|
const record = storage[id]
|
|
if (!record) {
|
|
const value = getter()
|
|
storage[id] = [value, keys]
|
|
return value
|
|
} else {
|
|
const [prevValue, prevKeys] = record
|
|
record[1] = keys
|
|
if (keys) {
|
|
for (let i = 0; i < keys.length; i++) {
|
|
if (keys[i] !== prevKeys[i]) {
|
|
return (record[0] = getter())
|
|
}
|
|
}
|
|
}
|
|
return prevValue
|
|
}
|
|
}
|